TransactionDefinition.PROPAGATION_REQUIRED: According to spring's definition, PROPAGATION_REQUIRED requires transaction support. If not, it will create a new transaction by itself
1、type 0 :TransactionDefinition.PROPAGATION_REQUIRED
TransactionDefinition.PROPAGATION_REQUIRED: According to spring's definition, PROPAGATION_REQUIRED requires transaction support. If not, it will create a new transaction by itself
We perform the following tests:
A. In the case of external transactions: http://localhost:8080/test1?type=0
DEBUG 137 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Acquired Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@1512c465] for JDBC transaction DEBUG 143 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Switching JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@1512c465] to manual commit INFO 149 INFO com.sapling.project.module.biz.TransactionTest - [outerTransaction]current transaction name : outerTransaction INFO 151 INFO com.sapling.project.module.biz.TransactionTest - {name:0} DEBUG 263 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Participating in existing transaction INFO 263 INFO com.sapling.project.module.biz.TransactionTest - [doInnerTransaction 0 ]current transaction name : outerTransaction INFO 263 INFO com.sapling.project.module.biz.TransactionTest - {name:0} INFO 267 INFO com.sapling.project.module.biz.TransactionTest - [doInnerTransaction]current transaction outerTransaction commit. DEBUG 268 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Initiating transaction commit DEBUG 268 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Committing JDBC transaction on Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@1512c465] DEBUG 274 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Releasing JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@1512c465] after transaction DEBUG 274 DEBUG o.springframework.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource INFO 275 INFO com.sapling.project.module.biz.TransactionTest - [outerTransaction]current transaction null commit.
Data table inserted successfully
+----+----------+------+--------+ | id | name | sex | status | +----+----------+------+--------+ | 8 | 0-true | NULL | NULL | | 9 | i-0-true | NULL | NULL |
B. When there is no external transaction: http://localhost:8080/test3?type=0
INFO 093 INFO com.sapling.project.module.biz.TransactionTest - [outerTransaction] did not have transaction INFO 094 INFO com.sapling.project.module.biz.TransactionTest - {name:0} DEBUG 094 DEBUG o.springframework.jdbc.datasource.DataSourceUtils - Fetching JDBC Connection from DataSource DEBUG 104 DEBUG o.springframework.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource DEBUG 104 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Creating new transaction with name [null]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT DEBUG 104 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Acquired Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@1512c465] for JDBC transaction DEBUG 104 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Switching JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@1512c465] to manual commit INFO 106 INFO com.sapling.project.module.biz.TransactionTest - [doInnerTransaction 0 ]current transaction name : null INFO 107 INFO com.sapling.project.module.biz.TransactionTest - {name:0} DEBUG 111 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Initiating transaction commit DEBUG 111 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Committing JDBC transaction on Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@1512c465] DEBUG 118 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Releasing JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@1512c465] after transaction DEBUG 119 DEBUG o.springframework.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource INFO 119 INFO com.sapling.project.module.biz.TransactionTest - [doInnerTransaction]current transaction null commit.
Data table inserted successfully
mysql> select * from sys_user -> ; +----+----------+------+--------+ | id | name | sex | status | +----+----------+------+--------+ | 8 | 0-true | NULL | NULL | | 9 | i-0-true | NULL | NULL | | 10 | o-0-true | NULL | NULL | | 11 | i-0-true | NULL | NULL | +----+----------+------+--------+ 4 rows in set (0.00 sec)
C. In the case of external transactions, but internal exceptions:
The system reported a 500 error, and the log is as follows:
165 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Creating new transaction with name [null]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT 172 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Acquired Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@5d7163af] for JDBC transaction 172 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Switching JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@5d7163af] to manual commit 174 INFO com.sapling.project.module.biz.TransactionTest - [outerTransaction]current transaction name : outerTransaction 174 INFO com.sapling.project.module.biz.TransactionTest - {name:o-0-true} 178 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Participating in existing transaction 178 INFO com.sapling.project.module.biz.TransactionTest - [doInnerTransaction 0 ]current transaction name : outerTransaction 178 INFO com.sapling.project.module.biz.TransactionTest - {name:11111111111111111111111111111} 284 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Participating transaction failed - marking existing transaction as rollback-only 284 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Setting JDBC transaction [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@5d7163af] rollback-only 284 INFO com.sapling.project.module.biz.TransactionTest - [doInnerTransaction ]current transaction outerTransaction rollback. 284 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Global transaction is marked as rollback-only but transactional code requested commit 284 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Initiating transaction rollback 284 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Rolling back JDBC transaction on Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@5d7163af] 319 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Releasing JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@5d7163af] after transaction 319 DEBUG o.springframework.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource 326 DEBUG org.springframework.web.servlet.DispatcherServlet - Could not complete request org.springframework.transaction.IllegalTransactionStateException: Transaction is already completed - do not call commit or rollback more than once per transaction
It can be seen that the transaction is rolled back directly in the internal method, the entire transaction has been completed, and an error is reported when the external transaction performs the rollback operation. Here you can add !status.isCompleted before the rollback operation. () to check whether the transaction is completed, and it does not need to be rolled back when it is completed.
Checking the database, it can be seen that the transaction has failed as a whole, and neither the data of the internal method nor the external method has been inserted successfully:
mysql> select * from sys_user; +----+----------+------+--------+ | id | name | sex | status | +----+----------+------+--------+ | 8 | 0-true | NULL | NULL | | 9 | i-0-true | NULL | NULL | | 10 | o-0-true | NULL | NULL | | 11 | i-0-true | NULL | NULL | +----+----------+------+--------+ 4 rows in set (0.00 sec)
D. There is no external transaction, and the internal execution fails:
.964 INFO com.sapling.project.module.biz.TransactionTest - [outerTransaction] did not have transaction .964 INFO com.sapling.project.module.biz.TransactionTest - {name:0-true} .964 DEBUG o.springframework.jdbc.datasource.DataSourceUtils - Fetching JDBC Connection from DataSource .973 DEBUG o.springframework.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource .973 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Creating new transaction with name [null]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT .973 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Acquired Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@5b773cec] for JDBC transaction .973 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Switching JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@5b773cec] to manual commit .974 INFO com.sapling.project.module.biz.TransactionTest - [doInnerTransaction 0 ]current transaction name : null .974 INFO com.sapling.project.module.biz.TransactionTest - {name:11111111111111111111111111111} .978 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Initiating transaction rollback .978 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Rolling back JDBC transaction on Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@5b773cec] .982 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Releasing JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@5b773cec] after transaction .982 DEBUG o.springframework.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource .982 INFO com.sapling.project.module.biz.TransactionTest - [doInnerTransaction ]current transaction null rollback.
Database table query results:
mysql> select * from sys_user; +----+----------+------+--------+ | id | name | sex | status | +----+----------+------+--------+ | 8 | 0-true | NULL | NULL | | 9 | i-0-true | NULL | NULL | | 10 | o-0-true | NULL | NULL | | 11 | i-0-true | NULL | NULL | | 16 | 0-true | NULL | NULL | +----+----------+------+--------+ 5 rows in set (0.00 sec)
It can be seen that the failure of the inner transaction is different from the insert operation under the transaction.
It can be seen from the above execution results that the transaction in the required propagation mode will join the existing transaction in the case of an existing transaction, and execute according to the process of the existing transaction. If there is no transaction, a new transaction will be executed. , the result of its execution does not affect other transactions.