I. Preface:
In the previous blog post, we used the template mode for transaction management, and the code looked very concise, but it was still not perfect.
We still need to write and transaction-related code at the service layer, i.e. we need to declare a transactiontemplate on the service layer.
In this article, we will use the dynamic proxy provided by Java to complete the transaction, and you will see that neither the service layer nor the DAO layer
have transaction processing code
Two. Example:
1. Code structure diagram:
2. Transactionproxy
/** * Dynamic proxy */public class Transactionproxy {public static object Proxyfor (Object object) {return proxy.newproxyinstance (ob Ject.getclass (). getClassLoader (), Object.getclass (). Getinterfaces (), New Transactioninvocationhandler (object));}} Class Transactioninvocationhandler implements Invocationhandler {private Object proxy; Transactioninvocationhandler (Object object) {This.proxy = object;} public object invoke (Object obj, Method method, object[] objects) throws Throwable {transactionmanager.begintransaction ( Object result = null;try {//Call business method result = Method.invoke (proxy, objects); Transactionmanager.commit ();} catch (Exception e) {transactionmanager.rollback ();} finally {transactionmanager.close ();} return result;}}
intercepts the service layer's transfer method, joins the transaction preparation before the call, and then invokes the original transfer method,
Then, depending on whether the transfer method performs a successful decision, commit or rollback
3. Interface Class Accountservice
/** * Business Logic Layer Interface */public interface accountservice{public void Transfer (account Outaccount, account Inaccount, int. money) THR oWS SQLException;}
With dynamic proxies, the proxy class and the proxy class must implement the same interface
4. Business Implementation Class Accountserviceimpl
/** * Business Logic Layer */public class Accountserviceimpl implements Accountservice {@Overridepublic void transfer (account Outaccount , account Inaccount, int. money) throws SQLException {//Query two accounts accountdao Accountdao = new Accountdao (); outaccount = Accoun Tdao.findaccountbyid (Outaccount.getid ()); inaccount = Accountdao.findaccountbyid (Inaccount.getid ());//Transfer-Modify the original account amount Outaccount.setmoney (Outaccount.getmoney ()-Money), Inaccount.setmoney (Inaccount.getmoney () + money);// Update Account Amount accountdao.update (Outaccount); accountdao.update (Inaccount);}}
5. Test class:
public class Transfertest {@Testpublic void Transfertest () throws SQLException {account out = new account (); Out.setid (1); A Ccount in = new account (); In.setid (2); Accountservice accountservice = new Accountserviceimpl ();//Get Accountservice proxy accountservice accountserviceproxy = ( Accountservice) transactionproxy.proxyfor (Accountservice); Accountserviceproxy.transfer (out, in, 100);}}
Call the Proxyfor method, pass in the object that needs to be proxied, return a proxy object, the proxy object bar will be added to the transaction with the transfer method
Three. Summary:
With dynamic proxies, all public methods in the Accountserviceimpl are proxied, that is, they are all added to the transaction, which is possible for all methods in the service layer that need to deal with the database. However, the public method that does not need to deal with the database in the service layer does not make an error, but it seems redundant.
Reference article: http://www.davenkin.me/post/2013-02-24/40049235086
Java Transactions (v)-Using dynamic proxies