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() がロールバックされない場合のように、例外が発生した場合でも、トランザクションがコミットされます。スプリングログを調べてみたところ、例外後にトランザクションがコミットされていることがわかります

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 メソッドを囲むトランザクション プロキシが、アタッチされたトランザクション (サービス レイヤーによって作成された) をロールバックのみとしてマークし、サービス レイヤーからコントロールが返されたときにトランザクションマネージャーは変更をコミットしようとしましたが、読み取り専用としてマークされていることがわかりました。そのため、エラーが発生しています。

于 2013-02-19T05:09:34.810 に答える