Class
Class B
Class C
Scenario: Class A is nested, Class B is nested, and class C is nested. transactions are controlled by spring.
Requirement: When Class C reports an exception, subsequent logical execution of Class A and Class B is not affected.
Problem: Class C reports an exception. The subsequent logic of Class A and Class B can be executed, but the data is rolled back.
Analysis: the preliminary analysis is: The Spring transaction control is not strict. For a transaction controlled by spring, as long as the class referenced in Class C throws an exception, the transaction will be marked as a rollback. In order to avoid this situation, it is best to set the related class, instead of letting spring control the transaction.
Solution: open transactions are displayed in Class C. The method is as follows:
// Distribution of sales management data to the province (requirement: whether the delivery is successful without affecting subsequent code execution; therefore, a new transaction must be started)
// Start a new transaction to prevent confusion with other transactions
Datasourcetransactionmanager transactionmanager = (datasourcetransactionmanager) springcontextfactory
. Getbean ("transactionmanager ");
Defaulttransactiondefinition def = new defaulttransactiondefinition ();
Def. setpropagationbehavior (transactiondefinition. propagation_requires_new); // transaction isolation level, enabling new transactions, unlike Class A and Class B.
Transactionstatus status = transactionmanager. gettransaction (DEF); // obtain the Transaction Status
Try {
* ************* Code logic ****************
Transactionmanager. Commit (Status );
} Catch (exception e ){
// Todo: handle exception
Transactionmanager. rollback (Status );
}
Supplement:
Configure Class C to prevent Spring transaction control, and class C shows that transactions are enabled. Do not throw an exception in the class referenced in Class C.
In addition, enable a new transaction in Class A before calling Class B.
2. Remarks:
Q: How to manually submit spring-managed transactions? Note: The Spring transaction level is propagation_required.
Answer: first, start a transaction at the beginning of the class. If the isolation level of the transaction is propagation_required, manual transaction commit does not work.
The isolation level of the transaction must be configured as. propagation_requires_new to manually commit the transaction.
// Start a new transaction to prevent confusion with other transactions
Datasourcetransactionmanager transactionmanager = (datasourcetransactionmanager) springcontextfactory
. Getbean ("transactionmanager ");
Defaulttransactiondefinition def = new defaulttransactiondefinition ();
Def. setpropagationbehavior (transactiondefinition. propagation_requires_new); // transaction isolation level, enabling new transactions, unlike Class A and Class B.
Transactionstatus status = transactionmanager. gettransaction (DEF); // obtain the Transaction Status