(对Spring来说仍然有点新鲜)
我需要一个同时@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
方法@Scheduled
,但离开了@Transactional
但我仍然得到同样的例外。我还尝试将@Transactional
放在我的DAO方法上并从我的服务方法中删除它:结果相同。
答案 0 :(得分:17)
使用@Transactional
注释的方法创建单独的类,并在@Scheduled
带注释的方法中调用此方法。 spring将通过代理进行调用并正确处理@Transactional
。
编辑: 另请查看您的DAO方法并确保它不会手动提交或回滚交易
答案 1 :(得分:0)
就我而言
private void button1_Click(object sender, EventArgs e)
{
foreach (object s1 in ChGetQtnNumber.CheckedItems)
{
DataRowView drv = (DataRowView)s1;
string getdetailofQtn = drv["ColumnName"].ToString();
MessageBox.Show(getdetailofQtn);
}
}
未使用。在将此注释添加到我的@Configuration类之一后,它开始工作。