1

我有以下类和方法如下:

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
为什么需要默认的交易传播时会发生此错误?谁能解释一下?

4

1 回答 1

2

仅凭您提供的数据是不够的。尝试@Transactional("emp")从类中删除EmployeeService并将其放在方法级别。这将减轻数据库启动不需要的事务。

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

将整个链添加到您的问题中,还将AutowiredcheckEmployee.

请记住,@Transactional仅在通过 a 后才适用,proxy并且该方法必须是可见的(无private方法)。您private method checkEmployee没有应用它的@Transactional注释,它确实是从它的调用者继承的。只要它的调用者public用@Transactional 注释并从代理调用(例如自动装配)。

另一件可以帮助的事情是在对 in 的调用中设置一个断点saveOrUpdatesaveEmployee检查有多少事务在db. 在mysql中SHOW INNODB STATUS\G

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

于 2012-08-16T07:57:47.530 回答