問題
19/01/29 14:41:31 [main]: DEBUG datasource.DataSourceTransactionManager: Creating new transaction with name [ChansonTransaction]: PROPAGATION_REQUIRES_NEW,ISOLATION_READ_COMMITTED
19/01/29 14:41:31 [main]: DEBUG datasource.DataSourceTransactionManager: Acquired Connection [jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=UTF-8&useSSL=false, UserName=root@localhost, MySQL Connector Java] for JDBC transaction
19/01/29 14:41:31 [main]: DEBUG datasource.DataSourceUtils: Changing isolation level of JDBC Connection [jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=UTF-8&useSSL=false, UserName=root@localhost, MySQL Connector Java] to 2
19/01/29 14:41:31 [main]: DEBUG datasource.DataSourceTransactionManager: Switching JDBC Connection [jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=UTF-8&useSSL=false, UserName=root@localhost, MySQL Connector Java] to manual commit
19/01/29 14:41:31 [main]: DEBUG core.JdbcTemplate: Executing prepared SQL update
19/01/29 14:41:31 [main]: DEBUG core.JdbcTemplate: Executing prepared SQL statement [UPDATE t_user SET password=? WHERE user_name =?]
19/01/29 14:41:31 [main]: DEBUG core.JdbcTemplate: SQL update affected 1 rows
19/01/29 14:41:31 [main]: DEBUG datasource.DataSourceTransactionManager: Initiating transaction rollback
19/01/29 14:41:31 [main]: DEBUG datasource.DataSourceTransactionManager: Rolling back JDBC transaction on Connection [jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=UTF-8&useSSL=false, UserName=root@localhost, MySQL Connector Java]
19/01/29 14:41:31 [main]: DEBUG datasource.DataSourceUtils: Resetting isolation level of JDBC Connection [jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=UTF-8&useSSL=false, UserName=root@localhost, MySQL Connector Java] to 4
19/01/29 14:41:31 [main]: DEBUG datasource.DataSourceTransactionManager: Releasing JDBC Connection [jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=UTF-8&useSSL=false, UserName=root@localhost, MySQL Connector Java] after transaction
19/01/29 14:41:31 [main]: DEBUG datasource.DataSourceUtils: Returning JDBC Connection to DataSource
Exception in thread "main" org.springframework.transaction.IllegalTransactionStateException: Transaction is already completed - do not call commit or rollback more than once per transaction
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:697)
at springjiemi.platformtransaction.UserService.update(UserService.java:42)
at springjiemi.platformtransaction.UserService.main(UserService.java:50)
分析
日誌顯示存在事務多次提交的問題。
分析了一下源代碼:
public void read() {
//手動開啓事務
TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
try {
int i=1/0;
} catch (Exception e) {
//手動回滾事務
dataSourceTransactionManager.rollback(transactionStatus);
}
//手動提交事務
dataSourceTransactionManager.commit(transactionStatus);//提交
}
由於異常被catch
,而在catch
時,進行了事務回滾
,正常在此應該退出方法處理(程序直接返回或者拋出異常),但事實上程序直接執行了後續的代碼:dataSourceTransactionManager.commit(transactionStatus);
所以報錯。
解決
解決方法:在catch過程中,拋出異常,結束方法執行。
public void read() {
//手動開啓事務
TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
try {
int i=1/0;
} catch (Exception e) {
//手動回滾事務
dataSourceTransactionManager.rollback(transactionStatus);
throw e;
}
//手動提交事務
dataSourceTransactionManager.commit(transactionStatus);//提交
}