我正在使用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
如果我在DAO方法之前放置@Transactionl,事务会回滚但我得到500错误,说明事务已标记为回滚。我错过了什么吗?
答案 0 :(得分:3)
删除try {} catch {}
阻止。
仅当异常从方法返回给调用者时才会发生事务回滚。
在您的情况下,您使用空try..catch
块以静默方式终止异常,因此异常永远不会传播到事务管理器,因此事务管理器永远不会获得回滚信号。
如果注释dao
,当从dao层抛出异常时,围绕dao方法的事务代理将附加事务(由服务层创建)标记为仅回滚,然后在控件时从服务层返回事务管理器尝试提交更改但发现它被标记为只读。这就是错误即将到来的原因。