First, the four characteristics of transactions (ACID)
1. Atomicity: The statements that make up a transaction form a logical unit and cannot be executed only in part;
2. Consistency: Before and after the execution of transaction processing, the database is consistent with the theoretical value (database integrity constraint);
3. Isolation: One transaction and another transaction do not affect each other;
4. Durability: The effect of transaction processing can be preserved forever.
2. Isolation level
1. Multi-threaded concurrent execution may cause the following three problems:
Dirty reads: A transaction reads data written by a parallel transaction that is not committed by another transaction;
Non-repeatable reads: A transaction re-reads previously read data and finds that the data has been modified by another committed transaction;
Phantom read: A transaction re-executes a query, returning a set of eligible rows that have changed due to the most recently committed transaction
2. Isolation level
Read uncommitted: unresolved
Read committed: resolved: dirty read
Repeatable read: resolved: dirty read, non-repeatable read
Serializble: resolved: dirty reads, non-repeatable reads, phantom reads
3. Set the isolation level
connection.setTransactionlsolation(Connection.transaction level)
MySql defaults to submitted;
Three, Java operation
Reference: https://www.cnblogs.com/zzzzw/p/4869334.html
1. Open transaction (non-autocommit): used for batch commit or transaction integrity operation.
By default, database connections are in autocommit mode. Each SQL statement is committed to the database once executed. Once a command has been committed, it cannot be rolled back.
When using transactions, you need to turn off this default:
conn.setAutoCommit(false);
A statement object can now be created using the usual methods:
Statement stat = conn.createStatement();
Then call the executeUpdate method any number of times:
stat.executeUpdate(command1); stat.executeUpdate(command2); ...
If there is no error after executing all commands, then call the commit method:
conn.commit();
If an error occurs, call:
conn.rollback();
At this point, the program will automatically undo all statements since the last commit. When a transaction is interrupted by a SQLException, the typical method is to initiate a rollback operation.
2. Savepoint: Undo some operations in a transaction
When using some drivers, the use of save points allows for more fine-grained control over the rollback operation. Creating a savepoint means just returning to that point later, not the beginning of the transaction. E.g,
Statement stat = conn.createStatement(); //Open a transaction; rollback() returns here stat.executeUpdate(command1); Savepoint svpt = conn.setSavepoint(); //Set the savepoint; rollback(svpt) returns here stat.executeUpdate(command2); if(...) conn.rollback(svpt); //Revocation of the effect of command2 ... conn.commit(); // Don't forget to commit the transaction at the end, otherwise the operations that need to be submitted and saved will not be saved in the database
When a savepoint is no longer needed, it must be released:
conn.releaseSavepoint(svpt);
3. Batch update :
Suppose there is a program that needs to execute many INSERT statements in order to fill the data into the database table. At this time, the method of batch update can be used to improve the performance of the program. When using batch update, a sequence of statements is collected and committed simultaneously as a batch of operations.
Note: Use the supportsBatchUpdates method in the DatabaseMetaData interface to find out whether the database supports this feature.
Statements in the same batch can be operations such as INSERT, UPDATE, and DELETE, or database-defining statements such as CREATE TABLE and DROP TABLE. However, adding a SELECT statement in a batch throws an exception (conceptually, a SELECT statement in a batch doesn't make sense because it returns a result set, without updating the database).
In order to perform batch processing, a Statement object must first be created using the usual method:
Statement stat = conn.createStatement();
The addBatch method should now be called instead of the executeUpdate method:
String command = "CREATE TABLE..." stat.addBatch(command); while(...){ command = "INSERT INTO ... VALUES("+...+")"; stat.addBatch(command); }
Finally, commit the entire bulk update statement:
int[] counts = stat.executeBatch();
Calling the executeBatch method will return an array of records for all submitted statements.
In order to properly handle errors in batch mode, operations performed in batches must be treated as a single transaction. If a batch update fails during execution, it must be rolled back to the state it was in before the batch operation started.
First, turn off autocommit mode, then collect the bulk operation, execute and commit the operation, and finally restore the original autocommit mode:
boolean autoCommit = conn.getAutoCommit(); conn.setAutoCommit(false); Statement stat = conn.getStatement(); ... //keep calling stat.addBatch(...); ... stat.executeBatch(); conn.commit(); conn.setAutoCommit(true);
4. Small example (open, commit, rollback transaction)
//update student information public void update(Student s) { Connection connection = JDBCUtil_C3P0.getConnection(); try { //Turn off transaction auto-commit (open transaction) connection.setAutoCommit(false); //Find the student's original class in the database int oldclazzid = studentDao.findById(s.getId()).getClazz().getId(); //If the student's class changes, modify the class table if(oldclazzid !=s.getClazz().getId()){ //Add a student to the new class transferred to clazzDao.addClazzCount(connection, s.getClazz().getId()); //Reduce one student from the old class where he was originally clazzDao.subClazzCount(connection, oldclazzid); //Test the transaction, manually throw an SQL exception //throw new SQLException("Operation exception"); } //modify student information studentDao.updateStudent(connection, s); //If there is no exception in all the above operations, submit the transaction connection.commit(); } catch (SQLException e) { e.printStackTrace (); //Once there is an exception in any step of the transaction, the transaction will be rolled back try { connection.rollback(); } catch (SQLException e1) { e1.printStackTrace(); } }finally{ //Close the connection resource clazzDao.close(connection); studentDao.close(connection); } }