(Immer noch ein bisschen neu zu Frühling)Spring: @Transactional @Scheduled Methode löst Transaction
Ich brauche eine Service-Methode haben, die zur gleichen Zeit ist @Scheduled
und @Transactional
, so dass ich ein DAO nennen erhalten in es.
Deklarative Transaktionen sind aktiviert, der Transaktionsmanager ist ein org.springframework.orm.hibernate3.HibernateTransactionManager
, der auf einer Hibernate-Sitzungsfactory basiert.
Die Serviceklasse implementiert keine Schnittstelle, daher wird ein CGLIB-Proxy verwendet.
Diese Einrichtung funktioniert im Allgemeinen gut (Methoden, die aus dem Web-Stack aufgerufen werden, d. H. Struts), aber diese Methode löst beim Aufruf durch den Scheduler eine Ausnahme aus.
Hier sind die entsprechenden Bits des Codes:
Die Service-Methode (die Klasse ClientWakeAndTerminateManager
genannt):
@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
}
Relevante Teile meines Anwendungskontext:
<!-- 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>
Ausnahmestapel Spur:
[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
Der Stack-Trace scheint mir zu sagen, dass ein Transaktions-Proxy tatsächlich verwendet wird, so dass ich diese Ausnahme nicht verstehe. Hilfe !
EDIT:
ich durch die @Transactional
und die @Scheduled
Anmerkungen zu trennen versucht:
- Erstellen Sie eine neue Klasse/Bean, die die
@Scheduled
Methode - Injizieren Sie meinen Dienst zu dieser Bohne contaisn
- Entfernt die
@Scheduled
von meiner ursprünglichen Methode, aber verließ die@Transactional
Aber ich bekomme immer noch die selbe Ausnahme. Ich habe auch versucht, die @Transactional
auf meine DAO-Methode zu setzen und sie von meiner Service-Methode zu entfernen: das gleiche Ergebnis.
zurück dies passieren kann, wenn bereits begangen oder rückgängig gemachte Transaktion versucht – wedens
können Sie Ihre dao Methode zeigen, zu begehen oder Rollback? – wedens
OK, meine DAO-Methode war die Schuldige. Ich fing an, es zu vermuten, und dann machte dein Kommentar mich zweimal auf. Die Methode enthielt also einige übriggebliebene manuelle Session-Commits (ich modernisiere diese App kürzlich und "spring" sie aus), als der Transaktions-Proxy Calls anrief, scheiterte es, weil es bereits commited war! Vielen Dank für Ihre Zeit. Wenn Sie Ihre Antwort bearbeiten, um die DAO-Methode zu erwähnen, akzeptiere ich sie. –