Transaction marked as rollback only异常
今天在进行数据库操作时出现:Transaction rolled back because it has been marked as rollback only异常,刚开始没仔细看一直以为是spring的配置文件,因为我的spring配置事务片段如下: <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="get*" read-only="true" /> <tx:method name="*" /> </tx:attributes> </tx:advice> 我这里将service的所有get方法定义为只读事务,起初以为是这里的配置文件,所就将get的只读去掉,可仍然出现类似的错误。可见问题不是这个事务配置的问题,经过google一番后,应该是事务被提交了两次导致的错误。再仔细查看代码发现是在service中嵌套调用了另外一个service的更新操作,从而导致了事务被两次提交。代码类似如下: ... public void update() { MyObj obj1 = aservice.get(1); aservice.update(obj1); Query query = em.createQuery("UPDATE ...."); query.executeUpdate(); } ... update方法是一个service的方法,在该方法中调用了另外一个aservice的update方法,由于get方法是只读事务,所以第一条语句不会报错,当aservice执行完update后,其实事务已经被提交了,同时spring将该事务标志为rollback only,等到最后执行executeUpdate方法时,由于事务已经提交,所以就会被抛出前面提到的异常。可见,spring在处理事务时,多个service嵌套调用时使用的都是同一个事务,而不是每个不同的方法都使用新事务。?
?如果要采用spring的线程池进行后台的业务处理的话,尽量把业务方法重构到一个service里面进行调用,否则也会报告上面的错误。
更加详细的资料请参阅 http://openmrs-mailing-list-archives.1560443.n2.nabble.com/transaction-rollback-error-td1659793.html
?