簡體   English   中英

Spring:@Transactional @Scheduled方法拋出TransactionException

[英]Spring : @Transactional @Scheduled method throws TransactionException

(還是有點新的春天)

我需要一個同時具有@Scheduled@Transactional的服務方法,以便我可以在其中調用DAO。

啟用聲明式事務,事務管理器是基於hibernate會話工廠的org.springframework.orm.hibernate3.HibernateTransactionManager

服務類不實現任何接口,因此使用CGLIB代理。

這個設置一般工作正常(從Web堆棧調用的方法,即Struts),但是這個方法在調度程序調用時引發異常。

以下是相關的代碼:

服務方法(該類稱為ClientWakeAndTerminateManager ):

@Scheduled(initialDelay = 5000, fixedRateString = "${rmi.server.threads.clientsScheduleManagement.rate}")
    @Transactional(readOnly = true)
    public void runCheck(){

        //Call a read-only DAO method (the DAO is @Autowired as a class field)

        //do some stuff with the data loaded from DB

    }

我的應用程序上下文的相關部分:

<!-- switch on the transactional infrastructure -->
    <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>

    <!-- Utility class to execute transactional code where use of annotation is not possible -->
    <bean class="org.springframework.transaction.support.TransactionTemplate" id="txTemplate">
        <constructor-arg name="transactionManager" ref="transactionManager"/>
    </bean>

    <!-- Transaction manager based on Hibernate -->
    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="hibernateSessionFactory"/>
    </bean>

異常堆棧跟蹤:

[ERROR] : Unexpected error occurred in scheduled task.
org.springframework.transaction.TransactionSystemException: Could not commit Hibernate transaction; nested exception is org.hibernate.TransactionException: Transaction not successfully started
    at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:661)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:755)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:724)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:475)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:270)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:631)
    at ch.unine.sitel.lis.rmi.shared.ClientWakeAndTerminateManager$$EnhancerByCGLIB$$d8be4f34.runCheck(<generated>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:64)
    at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:53)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:351)
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:178)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:178)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722)
Caused by: org.hibernate.TransactionException: Transaction not successfully started
    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:127)
    at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:657)
    ... 22 more

堆棧跟蹤似乎告訴我確實使用了事務代理,所以我不理解這個異常。 救命 !

編輯:

我試圖通過以下方式將@Transactional@Scheduled注釋分開:

  • 創建一個包含@Scheduled方法的新類/ bean
  • 將我的服務注入此bean
  • 從我原來的方法中刪除了@Scheduled但是離開了@Transactional

但我仍然得到同樣的例外。 我還嘗試將@Transactional放在我的DAO方法上並從我的服務方法中刪除它:相同的結果。

使用@Transactional注釋的方法創建單獨的類,並在@Scheduled注釋的方法中調用此方法。 spring將通過代理進行調用並正確處理@Transactional

編輯:還要查看您的DAO方法並確保它不會手動提交或回滾事務

就我而言

@EnableTransactionManagement

沒用過。 將此注釋添加到我的@Configuration類之后,它開始工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM