Spring 3 JDBC事务管理器不工作



我使用的是Spring 3、MYSQL 5.5和tomcat 6。在我的应用程序中,我有3个DAO方法在服务类方法中一个接一个地执行。

@Transactional(propagation = Propagation.REQUIRED, rollbackFor = {
            Exception.class, RuntimeException.class })
   myService(){
      try {
         dao1.delete();
         dao1.update();
         dao1.save();
      } catch(){}
   }
Dao1 -
delete() throws exp1{ ---- some code ----}
save() throws exp1{ ---- some code ----}
update() throws exp2{ ---- some code ----}

现在,即使引发了异常,我的事务也会被提交,比如update()引发了异常delete()而save()没有回滚。我试着查看spring日志,我可以看到它在异常后提交了事务

20:00:29,071 DEBUG SQLErrorCodesFactory:198 - Looking up default SQLErrorCodes for DataSource [org.apache.tomcat.dbcp.dbcp.BasicDataSource@44755866]
20:00:29,078 DEBUG SQLErrorCodesFactory:216 - Database product name cached for DataSource [org.apache.tomcat.dbcp.dbcp.BasicDataSource@44755866]: name is 'MySQL'
20:00:29,079 DEBUG SQLErrorCodesFactory:174 - SQL error codes for 'MySQL' found
20:00:29,081 DEBUG SQLErrorCodeSQLExceptionTranslator:399 - Translating SQLException with SQL state '42S02', error code '1146', message [Table 'xxx.xxxx' doesn't exist]; SQL was [DELETE FROM xxxx WHERE xxxx=?] for task [PreparedStatementCallback]
20:00:29,086 DEBUG xxxServiceImpl:1022 - Returning result after deleting product : xxxx.xxxxx.xxxxx.xxx.ResultVO Object {Result: false, Error code: 1016, Error text: Error while deleting data. Please try again later}
20:00:29,094 DEBUG DataSourceTransactionManager:752 - Initiating transaction commit
20:00:29,097 DEBUG DataSourceTransactionManager:264 - Committing JDBC transaction on Connection [jdbc:mysql://localhost:3306/xxx?autoReconnect=true, UserName=root@localhost, MySQL-AB JDBC Driver]
20:00:29,113 DEBUG DataSourceTransactionManager:322 - Releasing JDBC Connection [jdbc:mysql://localhost:3306/xxx?autoReconnect=true, UserName=root@localhost, MySQL-AB JDBC Driver] after transaction
20:00:29,115 DEBUG DataSourceUtils:332 - Returning JDBC Connection to DataSource

如果我把@Transactionl放在DAO方法之前,事务会回滚,但我会得到500错误,说明事务已经标记为回滚。我是不是遗漏了什么?

移除try {} catch {}块。

只有当异常从方法抛出回调用方时,才会发生事务回滚。

在您的情况下,您使用一个空的try..catch块静默地杀死异常,因此异常永远不会传播到事务管理器,因此事务管理器永远不会得到回滚的信号。

在注释dao的情况下,当异常从dao层抛出时,dao方法周围的事务代理将附加事务(由服务层创建)标记为仅回滚,然后当控件从服务层返回时,事务管理器尝试提交更改,但发现它被标记为只读。这就是错误出现的原因。

最新更新