1, all along, in the management of things with spring, only know the use of declarative policy, that is, according to different data sources, configure a thing manager (TransactionManager), by configuring the Slice (PointCut) Apply to the appropriate business method or add @ttransactional annotations directly to the method.
This kind of transaction management is relatively simple to use, but the personal feeling of flexibility lacks a point.
2, recently looked at the company project Code, found a colleague in his module has used another kind of transaction management method, checked, Transactiontemplate is a programmatic transaction management. You need to implement transactions manually in each business method.
3, transactiontemplate use (not necessarily comprehensive):
A, in the DAO layer configuration file, configuration transactiontemplate, need to inject TransactionManager
<BeanID= "TransactionManager"class= "Org.springframework.jdbc.datasource.DataSourceTransactionManager"> < Propertyname= "DataSource"ref= "DataSource"/> </Bean> <BeanID= "Transactiontemplate"class= "Org.springframework.transaction.support.TransactionTemplate"> < Propertyname= "TransactionManager"> <refBean= "TransactionManager"/> </ Property> </Bean>
B, inject transactiontemplate into the business layer method and use:
First analyze the core principles of transactiontemplate:
Transactiontemplate Core Approach:
1 Public classTransactiontemplateextendsdefaulttransactiondefinition2 Implementstransactionoperations, Initializingbean {3 4 5 Public<T> T Execute (transactioncallback<t> action)throwsTransactionException {6 if( This. TransactionManagerinstanceofCallbackpreferringplatformtransactionmanager) {7 return((Callbackpreferringplatformtransactionmanager) This. TransactionManager). Execute ( This, action);8 }9 Else {TenTransactionstatus status = This. Transactionmanager.gettransaction ( This); One T result; A Try { -result =action.dointransaction (status); - } the Catch(RuntimeException ex) { - //Transactional code threw application exception-rollback - rollbackonexception (status, ex); - Throwex; + } - Catch(Error err) { + //Transactional code threw error-rollback A rollbackonexception (status, err); at Throwerr; - } - Catch(Exception ex) { - //transactional code threw unexpected exception-rollback - rollbackonexception (status, ex); - Throw NewUndeclaredthrowableexception (ex, "Transactioncallback threw undeclared checked exception"); in } - This. Transactionmanager.commit (status); to returnresult; + } -}
It can be inferred from the above code that the key code that actually executes the business method is: action.dointransaction (status);
Right, there is an entry transactioncallback<t>, look at the source of the interface:
1 Public Interface Transactioncallback<t> {25 T dointransaction (transactionstatus status); 6 7 }
This interface has only one dointransaction method, so it is very simple that we can put the business code in the Dointransaction by means of an anonymous inner class:
Examples are as follows:
1 PrivatePayorderdao Payorderdao; 2 3 protectedtransactiontemplate transactiontemplate; 4 5 /** 6 * Save Payment order7 */ 8 protectedPayorder Savepayreq (FinalPayorder Payorder) { 9 Ten @Autowired One Privatetransactiontemplate transactiontemplate; A - @Autowired - PrivatePayorderdao Payorderdao; the -Payorder order = (Payorder) This. Transactiontemplate -. Execute (NewTransactioncallback () { - @Override + PublicObject dointransaction (transactionstatus status) { - //See if a payment order already exists and return the order primary key if it already exists +Payorder payordertemp =Payorderdao.findorder (String A . ValueOf (Payorder.getpayorderid ())); at - //transaction type (PayType) converted by payment channel type (PAYCHANNELTYPE) - if(Payorder.getpaychannelid (). Equalsignorecase (Pay_chnl_act_bal)) {//account balance Payment -Payorder.setpaytype ("3"); -}Else if(Payorder.getpaychannelid (). Equalsignorecase (Pay_chnl_fast_pay)) {//Unicom Express Payment -Payorder.setpaytype ("4"); in}Else{//Online Banking Gateway Payment -Payorder.setpaytype ("2"); to } + - //The new payment amount is the same as the original order amount, if the inconsistency is incorrect the if(Payordertemp = =NULL) { *String orderId =Payorderdao.save (Payorder); $ Payorder.setpayorderid (orderId); Panax Notoginseng returnPayorder; -}Else { the returnpayordertemp; + } A } the }); + if("2". Equals (Order.getorderstate ())) {//2: Payment Success - Throw Newepaymentbizexception (StatusCode.DQSystem.PAY_FAIL, $"The same order cannot be paid again"); $}Else if(Payorder.getpayamt (). Longvalue ()! =Order.getpayamt () - . Longvalue ()) { - Throw Newepaymentbizexception (StatusCode.DQSystem.PAY_FAIL, the"The transaction amount is inconsistent with the original order"); -}Else { Wuyi returnPayorder; the } - Wu}
Another way to manage spring transactions--transactiontemplate programming transaction management simple Getting Started