Java Web----Service transaction

Source: Internet
Author: User

Use threadlocal in service to complete transactions and lay the groundwork for future learning of spring transactions!

1 transactions in DAO

public void xxx () {   Connection con = null;   try {      con = jdbcutils.getconnection ();      Con.setautocommitted (false);      Queryrunner qr = new Queryrunner ();      String sql = ...;      object[] params = ...;      Qr.update (con, SQL, params);      sql = ...;      object[] params = ...;      Qr.update (con, SQL, params);      Con.commit ();} catch (Exception e) {    try {       if (con! = null) {Con.rollback ();}} catch (Exception e) {}} finally {    try {       C On.close ();} catch (Exception e) {}}}

2 service is where transactions are handled

One thing we need to know is that DAO is not a place to handle transactions, because each method in DAO is an operation on the database, and the method in the service is the corresponding business logic. This means that we need to invoke multiple methods of DAO in a method in the service, and these methods should be in a transaction.

How can I make multiple methods of DAO use the same connection? Methods can not be obtained by themselves to connection, but by the outside world to pass in.

public void DaoMethod1 (Connection con, ...) {}public void daoMethod2 (Connection con, ...) {}

When you invoke multiple methods of DAO in a service, the same connection is passed.

public class Xxxservice () {   private Xxxdao dao = new Xxxdao ();   public void Servicemethod () {      Connection con = null;      try {         con = jdbcutils.getconnection ();         Con.setautocommitted (false);         Dao.daomethod1 (con, ...);         Dao.doamethod2 (con, ...);         Com.commint ();}  catch (Exception e) {   try {      con.rollback ();} catch (Exception e) {}} finally {   try {     con.close ()   } catch (Exception e) {}}}}

However, in the service should not appear connection, it should only appear in the DAO, because it is the JDBC thing, jdbc thing is used to connect the database, the connection database is DAO's thing!!! However, the transaction is the service thing, cannot put in the DAO!!!

3 modifying Jdbcutils

We put the opening and closing of the transaction into the Jdbcutils, call the Jdbcutils method in the service to complete the transaction processing, but there will be no more "taboo" in the service connection.

The method in DAO does not have to let the service pass the connection again. DAO will take the initiative to get connection objects from Jdbcutils, so that jdbcutils becomes the intermediary of DAO and service!

We add BeginTransaction () and RollbackTransaction () and the CommitTransaction () method in Jdbcutils. The code in this service is as follows:

public class Xxxservice () {   private Xxxdao dao = new Xxxdao ();   public void Servicemethod () {   try {      jdbcutils.begintransaction ();      Dao.daomethod1 (...);      DAO.DAOMETHOD2 (...);      Jdbcutils.committransaction ();} catch (Exception e) {   jdbcutils.rollbacktransaction ();}}}
Dao

public void daoMethod1 (...) {  Connection con = jdbcutils.getconnection ();} public void daoMethod2 (...) {  Connection con = jdbcutils.getconnection ();}

When the Jdbcutils.begintransaction () method is called in the service, jdbcutils to prepare a connection object that has already called the setauthcommitted (False) method. Because the DAO method is called immediately after calling Jdbcutils.begintransaction () in the service, the Jdbcutils.getconnection () method is called in the DAO method. This means that jdbcutils to return the connection object that was just prepared in the getconnection () method and has been set up for manual submission.


Create a Connectioncon property in Jdbcutils, and when it is null, the description has no transaction! When it is not NULL, indicates that the transaction is turned on.

    • You can invoke the "open transaction" method when the transaction is not turned on;
    • After the transaction is opened, the commit transaction and ROLLBACK TRANSACTION methods can be invoked;
    • The getconnection () method returns a connection from the connection pool when con is returned as con is not null, and then con is null.

BeginTransaction ()

Determines if con is null, and throws an exception if it is NOT NULL!

If con is null, then a connection object is obtained from the connection pool and assigned to con! Then set it to "submit manually".

Getconnection ()

Determines if con is null, if NULL indicates no transaction, then gets a connection from the connection pool to return;

If not NULL, the description has started the transaction, then the return Con property is returned. This shows that when Con is not null, the same connection object is returned regardless of how many times the getconnection () method is called.

CommitTransaction ()

Determines if con is null, if NULL, indicates that the transaction is committed without opening the transaction, then throws an exception;

If con is not null, then call Con's commit () method to commit the transaction;

Call the Con.close () method to close the connection;

con = null, which means the transaction has ended!

RollbackTransaction ()

Determines if con is null, if NULL, indicates that the transaction is rolled back without opening the transaction, then throws an exception;

If con is not null, then call con's rollback () method to roll the transaction back and forth;

Call the Con.close () method to close the connection;

con = null, which means the transaction has ended!

Jdbcutils.java

public class Jdbcutils {private static DataSource DataSource = new Combopooleddatasource ();p rivate static Connection con = Null;public static DataSource Getdatasource () {return DataSource;} public static Connection getconnection () throws SQLException {if (con = = null) {return datasource.getconnection ();} return con;} public static void Begintranscation () throws SQLException {if (con! = null) {throw new SQLException ("The transaction is already open and cannot be completed without ending the current transaction. Open the transaction! ");} con = datasource.getconnection (); Con.setautocommit (false);} public static void CommitTransaction () throws SQLException {if (con = = null) {throw new SQLException ("There is currently no transaction, so the transaction cannot be committed!") ");} Con.commit (); Con.close (); con = null;} public static void RollbackTransaction () throws SQLException {if (con = = null) {throw new SQLException ("There is currently no transaction, so the transaction cannot be rolled back!") ");} Con.rollback (); Con.close (); con = null;}}

4 Modify Jdbcutils again

Now Jdbcutils has a problem, if there are two threads! The first thread calls the BeginTransaction () method, and the other thread calls the BeginTransaction () method again, because con is no longer null, so it throws an exception.

We hope jdbcutils can be used in multi-threaded environment! This suggests that the best way is to provide a connection for each thread so that each thread can open its own transaction.

Do you remember the Threadlocal class?

public class Jdbcutils {private static DataSource DataSource = new Combopooleddatasource ();p rivate static threadlocal< connection> tl = new threadlocal<connection> ();p ublic static DataSource Getdatasource () {return DataSource;} public static Connection getconnection () throws SQLException {Connection con = tl.get (); if (con = = null) {return DataSource . getconnection ();} return con;} public static void Begintranscation () throws SQLException {Connection con = tl.get (); if (con! = null) {throw new Sqlexcepti On ("The transaction is already open and the transaction cannot be opened without ending the current transaction!") ");} con = datasource.getconnection (); Con.setautocommit (false); Tl.set (con);} public static void CommitTransaction () throws SQLException {Connection con = tl.get (); if (con = = null) {throw new sqlexcept Ion ("No transaction is currently present, so the transaction cannot be committed!") ");} Con.commit (); Con.close (); Tl.remove ();} public static void RollbackTransaction () throws SQLException {Connection con = tl.get (); if (con = = null) {throw new Sqlexce Ption ("There is currently no transaction, so the transaction cannot be rolled back!") ");} Con.rollback (); Con.close (); Tl.remove ();}}
5 Transfer Example

public class Accountdao {public void UpdateBalance (string name, double balance) throws SQLException {String sql = "Update Account set balance=balance+? where name=? "; Connection con = jdbcutils.getconnection (); Queryrunner qr = new Queryrunner (); Qr.update (con, SQL, balance, name);}}


public class Accountservice {private Accountdao dao = new Accountdao ();p ublic void Transfer (string from, string to, double Balance) {try {jdbcutils.begintranscation ();d ao.updatebalance (from,-balance);d ao.updatebalance (to, balance); Jdbcutils.committransaction ();} catch (Exception e) {try {jdbcutils.rollbacktransaction ();} catch (SQLException E1) {throw new RuntimeException (e);}}} Accountservice as = new Accountservice (); As.transfer ("Zs", "ls", 100);


Java Web----Service transaction

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.