Transaction is already completed - do not call commit or rollback more than once per transaction

問題

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);//提交


    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章