0

我正在使用 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 错误,说明事务已标记为回滚。我在这里错过了什么吗?

4

1 回答 1

3

删除try {} catch {}块。

仅当从方法将异常抛回给调用者时,才会发生事务回滚。

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

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

于 2013-02-19T05:09:34.810 回答