2012-08-16 74 views
1

时,我有以下的类和方法如下:死锁使用Spring的事务

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.stereotype.Component; 
import org.springframework.transaction.annotation.Transactional; 

@Component 
@Transactional("emp") 
public class EmployeeService { 

} 

@Component 
public class HumanResourceManager { 

[...] 

@Autowired 
private EmployeeService employeeService; 

@Transactional("emp") 
public void checkEmployee(Employee emp) { 

[..] 

employeeService.saveEmployee(emp); 

[...] 

} 

My Spring config: 

<bean id="employeeDataSource" 
     class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
     <property name="driverClassName" value="${employee.driverClassName}" /> 
     <property name="url" value="${employee.url}" /> 
     <property name="username" value="${employee.user}" /> 
     <property name="password" value="${employee.password}" /> 
    </bean> 

    <bean id="employeeSessionFactory" 
     class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> 
     <property name="dataSource" ref="employeeDataSource" /> 
     <property name="packagesToScan" value="com.xyz.employee.model" /> 
     <property name="hibernateProperties"> 
      <props> 
       <prop key="hibernate.dialect">${employee.dialect}</prop> 
       <prop key="hibernate.cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</prop> 
       <prop key="hibernate.show.sql">true</prop> 
      </props> 
     </property> 
    </bean> 

    <bean id="employeeTransactionManager" 
     class="org.springframework.orm.hibernate4.HibernateTransactionManager"> 
     <property name="sessionFactory" ref="employeeSessionFactory" /> 
     <qualifier value="emp" /> 
    </bean> 

    <tx:annotation-driven transaction-manager="employeeTransactionManager" /> 

我有例外org.hibernate.exception.LockAcquisitionException: ORA-00060: deadlock detected while waiting for resource!并且在异常堆栈跟踪中,此错误发生在方法checkEmployee
为什么当需要默认繁殖交易时出现此错误?任何人都可以解释吗?

回答

2

由您提供的数据是不够的。尝试从类EmployeeService中删除@Transactional("emp"),并将其置于方法级别。这将缓解数据库启动不必要的交易。

尝试启用debug日志级别为org.springframework.orm并查看发生了什么。

加入您的问题全部链接,也加入checkEmployee内的Autowired服务。

请注意,@Transactional仅适用于传递proxy后方法必须可见(无法使用private方法)。您的private method checkEmployee未应用其@Transactional注释,它确实从其调用者继承。只要其调用者是public注释@Transactional并从代理(例如autowired)调用。

另一件可以帮助的事情是在的saveEmployee调用中设置一个断点,并检查db中有多少个事务。 In mysql SHOW INNODB STATUS\G

当顶级方法(启动最内部事务)返回一个代理时,会发出提交。这适用于您开始的每项交易。

+0

它没有工作。事务的传播是REQUIRED意味着该线程只有1个事务,但死锁发生意味着有超过1个事务创建,他们尝试锁定和提交DB – Barcelona 2012-08-16 08:29:33

+0

该方法是公开的,只是我的打字错误:) – Barcelona 2012-08-16 08:38:13

+0

是在最后一个方法中对自动装配方法的任何其他调用? – ssedano 2012-08-16 08:40:02