Problems caused by transaction concurrency and solutions

Problems caused by transaction concurrency and solutions

problem:

  1. Dirty reads: Dirty reads occur when one transaction reads data that has been rewritten by another transaction but has not yet been committed. If the rewrite is rolled back later, the data obtained by the first transaction is invalid.
    1. time Withdrawal transaction A Deposit transaction B
      T1 Start transaction  
      T2   Start transaction
      T3   Check account balance is 1000 yuan
      T4   Remit 100 yuan and change the balance to 1100 yuan
      T5 Query account balance of 1100 yuan (read dirty data)  
      T6   Rollback
      T7 Withdrawal 1100  
      T8 Failed to commit transaction  

       

  2. Nonrepeatable read: Nonrepeatable read occurs when a transaction executes the same query twice or more, but gets different data each time. This is usually because another concurrent transaction was updated during the two queries.
    1. time Withdrawal transaction A Deposit transaction B
      T1 Start transaction  
      T2   Start transaction
      T3 Check account balance is 1000 yuan  
      T4   Remit 100 yuan and change the balance to 1100 yuan
      T5   Commit transaction
      T6    
      T7 Check account balance is 1100 yuan  
      T8 Commit transaction  
  3. Phantom read: Phantom read is similar to non-repeatable read. It happens when a transaction (T1) reads a few rows of data, and then another concurrent transaction (T2) inserts some data. In subsequent queries, the first transaction (T1) will find that there are more records that did not exist.
    1. time Enquiry about student affairs A Insert new student affairs B
      T1 Start transaction  
      T2   Start transaction
      T3 Enquiry for 10 students  
      T4   Insert 1 student
      T5 Enquiry for 11 students  
      T6   Commit transaction
      T7 Commit transaction  

Solution:

Database transaction isolation mechanism

 i. View getConnection() documentation

 ii. 1: read-uncommitted 2: read-committed 4: repeatable read 8: serializable (the number represents the corresponding value)

     Why use 1 2 4 8 instead of 1 2 3 4

     1=0000 2=0010 4=0100 8=1000 (high displacement calculation efficiency)

  1. As long as the database supports transactions, the first type of lost update is impossible
  2. read-uncommitted (allowing to read uncommitted data) Dirty read, phantom-read, non-repeatable read problems will occur
  3. read-commited (this is generally used in reading submitted data projects) will not appear dirty read, because only another transaction commits will read the results, but there will still be non-repeatable read and phantom-read. Use the read-commited mechanism to use pessimistic locking and optimistic locking to solve non-repeatable read and phantom-read problems
  4. repeatable read (other transactions cannot perform modification or insertion operations during transaction execution, which is safer)
  5. serializable solves all problems (sequential execution of transactions is not concurrent, it is rarely used in practice)

Set the transaction isolation level of hibernate (use hibernate.connection.isolation to configure values ​​1, 2, 4, 8)

i.hibernate.connection.isolation = 2 (If you do not set the default level that depends on the database itself)

ii. Use pessimistic locks to solve the problem of repeatable read ( depends on database locks )

  1. select ... for update
  2. Use another load method--load(xx.class, i, LockMode.Upgrade)
  • LockMode.None no lock mechanism, switch to this mode when the transaction ends
  • LockMode.read hibernate will automatically acquire the lock when querying
  • LockMode.write insert update hibernate will automatically acquire the lock
  • The above three lock modes are used internally by hibernate (no need to be set)
  • LockMode.UPGRADE_NOWAIT is the lock mode supported by ORACLE

Hibernate (JPA) optimistic locking (ReadCommitted)

Add the version attribute to the entity class (the database will also generate this field, the initial value is 0), and add it before the get method

@Version annotation, if the data in the row is not updated once during the operation, the version value is increased by 1, and you can determine whether the data has been modified by other transactions before the transaction is submitted.

Guess you like

Origin blog.csdn.net/qq_37192571/article/details/109102044