我有以下类和方法如下:
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
为什么在需要默认的事务传播时会发生此错误?谁能解释一下呢?
答案 0 :(得分:2)
使用您提供的数据是不够的。尝试从类@Transactional("emp")
中删除EmployeeService
并将其放在方法级别。这将减轻db启动不需要的事务。
尝试为debug
启用org.springframework.orm
日志级别,看看发生了什么。
将整个链添加到您的问题中,同时在Autowired
内添加对checkEmployee
服务的每次调用。
请记住@Transactional
仅在通过proxy
后才适用,且该方法必须可见(无private
方法)。您的private method checkEmployee
未应用其@Transactional
注释,它确实是从其调用者继承的。只要其调用者{@ 1}}使用@Transactional注释并从代理调用(例如,自动装配)。
另一件可以帮助的事情是在public
的{{1}}调用中设置断点,并检查saveOrUpdate
中有多少交易。在mysql saveEmployee
当顶级方法(启动最内部事务)返回trhu代理时发出提交。这适用于您开始的每笔交易。