A detailed explanation of Java transaction Management Study

  • 2020-06-15 09:02:05
  • OfStack

What are Java transactions

The common perception is that transactions are only database-related.

Transactions must be subject to the ACID principle as laid down by ISO/IEC. ACID is short for atomicity (atomicity), 1 tropism (consistency), isolation (isolation), and persistence (durability). The atomicity of the transaction means that any failure in the execution of the transaction will invalidate any changes made by the transaction. When a transaction fails, all data affected by the transaction should be restored to its pre-transaction state. Isolation means that changes to data during transaction execution are not visible to other transactions until they are committed. Persistence means that committed data should be in the correct state in the event of a transaction failure.

In common parlance, a transaction is a set of atomic operating-units, or a set of SQL instructions, from a database perspective. Either all of them are executed successfully, or if one of them is executed incorrectly for some reason, all of the previous instructions are revoked. To put it more simply: all or nothing.

Since the concept of a transaction comes from a database, what is an Java transaction? What's the connection?

In fact, an Java application is implemented via JDBC if you want to manipulate the database. The addition, modification and deletion are achieved indirectly through corresponding methods, and the control of transactions is also transferred to the Java program code. Therefore, the transaction of a database operation is customarily referred to as an Java transaction.

Characteristics of transactions:

1) Atomicity (atomicity) : A transaction is a logical unit of work for a database, and must be an atomic unit of work, with all or none of its data modifications.

2) 1 (consistency) : When a transaction is completed, all data must remain in a 1 state. In the relevant database, all rules must be applied to the modification of the transaction to maintain the integrity of all data.

3) Isolation (isolation) : The execution of a transaction cannot be affected by other transactions.

4) Persistence (durability) : once a transaction is committed, the operation of the transaction is permanently stored in DB. Even a rollback operation at this point cannot undo the changes.

Transactions (Transaction): A unit of concurrency control, a user-defined sequence of 1 operations. These operations are either all or none, an indivisible unit of work. Through transactions, sql server can bind a logically related set of operations from one to one so that the server maintains data integrity. Transactions usually start with begin transaction and end with commit or rollback. Commint represents commit, that is, commit all operations of the transaction. Specifically, all updates to the data in the transaction are written back to the physical database on disk, and the transaction ends normally. Rollback represents rollback, that is, some failure occurred during the process of the transaction running, the transaction cannot continue, the system reverses all completed operations on the database in the transaction, and rolls back to the state where the transaction started.

Auto commit transactions: Each individual statement is a transaction. One commit is implied after each statement. (the default)

Explicit transactions: Start with begin transaction display and end with commit or rollback.

Implicit transactions: When the connection operates in implicit transaction mode, the database engine instance of sql server automatically starts a new transaction after the current transaction is committed or rolled back. Instead of describing the beginning of a transaction, each transaction is committed or rolled back. But each transaction still ends explicitly with commit or rollback. After the connection is set to open, an implicit transaction is automatically started when the database engine instance executes any of the following statements for the first time: alter table, insert, create, open, delete, revoke, drop, select, fetch, truncate table, grant, update until the commit or rollback statement is issued. After the first transaction is committed or rolled back, the next time the connection executes any of the above statements, the database engine instance automatically starts a new transaction. This instance will continue to generate the implicit transaction chain until the implicit transaction pattern is closed.

JDBC transaction management

How to manage transactions when using JDBC. Let's go to code 1

The sample code


/** 
 * @Title: JDBCTrans.java 
 * @Package com.oscar999.trans 
 * @Description: 
 * @author XM 
 * @date Feb 14, 2017 4:38:27 PM 
 * @version V1.0 
 */ 
package com.oscar999.trans; 
 
import java.sql.Connection; 
import java.sql.DriverManager; 
import java.sql.SQLException; 
import java.sql.Statement; 
 
/** 
 * @author 
 * 
 */ 
public class JDBCTrans { 
 
 public JDBCTrans() { 
 
 } 
 
 /** 
 * 
 * @param sHostName 
 * @param sPortNumber 
 * @param sSid 
 * @param userName 
 * @param password 
 * @return 
 * @throws SQLException 
 */ 
 public Connection getConnection(String sHostName, String sPortNumber, String sSid, String userName, String password) throws SQLException { 
 Connection conn = null; 
 String url = getOraclURL(sHostName, sPortNumber, sSid); 
 conn = DriverManager.getConnection(url,userName,password); 
 return conn; 
 } 
 
 /** 
 * 
 * @param conn 
 * @param sql 
 * @throws SQLException 
 */ 
 public void add(Connection conn, String sql) throws SQLException { 
 Statement stmt = null; 
 try { 
  stmt = conn.createStatement(); 
  stmt.execute(sql); 
 } catch (SQLException e) { 
  // TODO Auto-generated catch block 
  e.printStackTrace(); 
 } finally { 
  if (stmt != null) 
  stmt.close(); 
 } 
 } 
 
 /** 
 * @param args 
 */ 
 public static void main(String[] args) { 
 // TODO Auto-generated method stub 
 String sHostName = ""; 
 String sPortNumber = ""; 
 String sSid = ""; 
 String userName = ""; 
 String password = ""; 
 
 sHostName = ""; 
 sPortNumber = ""; 
 sSid = ""; 
 userName = ""; 
 password = ""; 
 
 try { 
  Class.forName("oracle.jdbc.driver.OracleDriver"); 
 } catch (ClassNotFoundException e1) { 
  // TODO Auto-generated catch block 
  e1.printStackTrace(); 
 } 
  
 JDBCTrans jdbcTrans = new JDBCTrans(); 
 Connection conn = null; 
 try {  
  conn = jdbcTrans.getConnection(sHostName, sPortNumber, sSid, userName, password); 
  conn.setAutoCommit(false);// can't insert, update 
  
  //1. add SQL 
  String addSQL = "insert into TEST_TABLE values('name1','value1')"; 
  jdbcTrans.add(conn,addSQL); 
  
 } catch (SQLException e) { 
  // TODO Auto-generated catch block 
  e.printStackTrace(); 
 } finally { 
  /*if (conn != null) 
  { 
  try { 
   conn.close(); 
  } catch (SQLException e) { 
   // TODO Auto-generated catch block 
   e.printStackTrace(); 
  } 
  }*/ 
 } 
 
 } 
 
 private String getOraclURL(String sHostName, String sPortNumber, String sSid) { 
 String url = "jdbc:oracle:thin:@" + sHostName + ":" + sPortNumber + ":" + sSid; 
 return url; 
 } 
 
} 

For the above code, the explanation is as follows:

The above code has several explanatory sections:

1. conn.setAutoCommit(false) No transaction is committed after execution.

There is no impact on Select, but for Insert and Update the data will not be modified without submission

2. conn.close(); The code to close Connection has been dropped by Mark conn.setAutoCommit(false) The effect.

The reason is that Connection Close is executed once.

If Connection were using connection pooling in the application server, Connection would not be used by Close and would not execute Commit.

3. setAutoCommit(false) Usage is mostly committed when multiple statements are to be executed.

So the code that is closer to the actual situation for point 3 above is example code 2

Example code 2


/** 
 * @Title: JDBCTrans.java 
 * @Package com.oscar999.trans 
 * @Description: 
 * @author XM 
 * @date Feb 14, 2017 4:38:27 PM 
 * @version V1.0 
 */ 
package com.oscar999.trans; 
 
import java.sql.Connection; 
import java.sql.DriverManager; 
import java.sql.SQLException; 
import java.sql.Statement; 
 
/** 
 * @author 
 * 
 */ 
public class JDBCTrans { 
 
 public JDBCTrans() { 
 
 } 
 
 /** 
 * 
 * @param sHostName 
 * @param sPortNumber 
 * @param sSid 
 * @param userName 
 * @param password 
 * @return 
 * @throws SQLException 
 */ 
 public Connection getConnection(String sHostName, String sPortNumber, String sSid, String userName, String password) throws SQLException { 
 Connection conn = null; 
 String url = getOraclURL(sHostName, sPortNumber, sSid); 
 conn = DriverManager.getConnection(url, userName, password); 
 return conn; 
 } 
 
 /** 
 * 
 * @param conn 
 * @param sql 
 * @throws SQLException 
 */ 
 public void add(Connection conn, String sql) throws SQLException { 
 Statement stmt = null; 
 try { 
  stmt = conn.createStatement(); 
  stmt.execute(sql); 
 } catch (SQLException e) { 
  // TODO Auto-generated catch block 
  e.printStackTrace(); 
 } finally { 
  if (stmt != null) 
  stmt.close(); 
 } 
 } 
 
 /** 
 * @param args 
 */ 
 public static void main(String[] args) { 
 // TODO Auto-generated method stub 
 String sHostName = ""; 
 String sPortNumber = ""; 
 String sSid = ""; 
 String userName = ""; 
 String password = ""; 
 
 sHostName = ""; 
 sPortNumber = ""; 
 sSid = ""; 
 userName = ""; 
 password = ""; 
 
 try { 
  Class.forName("oracle.jdbc.driver.OracleDriver"); 
 } catch (ClassNotFoundException e1) { 
  // TODO Auto-generated catch block 
  e1.printStackTrace(); 
 } 
 
 JDBCTrans jdbcTrans = new JDBCTrans(); 
 Connection conn = null; 
 try { 
  conn = jdbcTrans.getConnection(sHostName, sPortNumber, sSid, userName, password); 
  conn.setAutoCommit(false);// can't insert, update 
 
  // 1. add SQL 1 
  String addSQL = "insert into TEST_TABLE values('name1','value1')"; 
  jdbcTrans.add(conn, addSQL); 
 
  //2. add SQL 2 
  addSQL = "insert into TEST_TABLE values('name2','value2')"; 
  jdbcTrans.add(conn, addSQL); 
  
  conn.commit(); 
 } catch (SQLException e) { 
  // TODO Auto-generated catch block 
  if(conn!=null){ 
   try { 
   conn.rollback(); 
   } catch (SQLException e1) { 
   e1.printStackTrace(); 
   } 
  }  
  e.printStackTrace(); 
 } finally { 
  if (conn != null) { 
  try { 
   conn.close(); 
  } catch (SQLException e) { 
   // TODO Auto-generated catch block 
   e.printStackTrace(); 
  } 
  } 
 } 
 
 } 
 
 private String getOraclURL(String sHostName, String sPortNumber, String sSid) { 
 String url = "jdbc:oracle:thin:@" + sHostName + ":" + sPortNumber + ":" + sSid; 
 return url; 
 } 
 
} 

It should be noted here that: conn.rollback();

rollback is required whenever an exception is executed. This step is essential

If no rollback occurs when an exception is executed. If an exception occurs after the first statement and con neither commits nor rolls back, the table is locked (if the oracle database is the row lock) and the lock has no chance to be released.

May be in operation con.close() The lock will be released, but if the application server USES the database connection pool, the connection will not be disconnected.

conclusion


Related articles: