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、メソッドレベルに配置してみてください。これにより、dbは不要なトランザクションを開始することができなくなります。

debugのログレベルを有効にしorg.springframework.ormて、何が起こっているかを確認してください。

Autowiredチェーン全体を質問に追加し、内のサービスへのすべての呼び出しも追加しますcheckEmployee

@Transactionalaを通過した後にのみ適用されproxy、メソッドが表示されている必要があることに注意してください(メソッドは表示されませんprivate)。あなたprivate method checkEmployeeはその注釈を適用していません@Transactional、それは確かにその呼び出し元から継承しています。呼び出し元publicに@Transactionalの注釈が付けられ、プロキシから呼び出されている限り(たとえば、自動配線)。

に役立つもう1つのことは、inの呼び出しにブレークポイントを設定し、にあるsaveOrUpdateトランザクションsaveEmployeeの数を確認することdbです。mysqlではSHOW INNODB STATUS\G

コミットは、最上位のメソッド(最も内部のトランザクションを開始したメソッド)がプロキシを返すときに発行されます。これは、開始するすべてのトランザクションに適用されます。

于 2012-08-16T07:57:47.530 に答える