Mysql transaction isolation levels and different isolation levels of concurrency affairs issues

First, the four characteristics of the transaction (ACID)

1, atomicity (Atomicity)

     After the transaction begins all operations, done either all or none of them. A transaction is an indivisible whole. Transaction errors in the implementation process, will be rolled back to the state before the transaction began, in order to ensure the integrity of transactions.

2. Consistency (Consistency)

    The transaction after the start and end, to ensure database integrity constraints correctness that is data integrity. Transfers, for example, A transfers to B, we must ensure that the money deducted A, B will be able to receive the money.

3, isolation (Isolation)

     Complete isolation between transactions, two transactions independently of each other. As A transfer to a bank card, to avoid too much at the same time the operating result in account the amount of defects, so before the end of A is not allowed into other transactions on this card operation.

4, persistent (Durability)

     Changes to the data of the transaction is permanent. Popular explanation after the transaction is completed, the operation should be carried out on the data off the disk (persistent). Once the transaction is completed is irreversible, the database performance for transaction once completed will not be rolled back.

Second, the problems caused by concurrent transactions

1, dirty reads

      A transaction reads another transaction has not yet submitted data called dirty read.

     For example: Transaction A transaction B reads the data update and rollback B, then A read data is dirty data

2, non-repeatable read

      The same transaction, the same data repeatedly read out is inconsistent.

      For example: Transaction A reads the same data multiple times, in the course of the transaction A transaction B read many times, the data were updated and submitted, the transaction A reads the same data multiple times lead to results inconsistent.

3, phantom read

      The same transaction, the amount of data in accordance with the same condition is inconsistent read-out (i.e. the number of pieces).

     For example: A transaction satisfies the condition once read many (such as age> = 10) data, transaction A transaction B during read many times, data is made to add or remove, resulting in multiple reads of the same transaction A data conditions, the amount of data inconsistency.

     Here to talk about the difference between non-repeatable read and phantom read:

  • But the 不可重复读:main point is that multiple reads a record, the record found some column values have been modified.
  • 幻读:Main point is that once read many records within a range of (direct access to all records, including the results or do statistical aggregation), found inconsistent results (generally refers to an increase in the standard file records, records should be considered to reduce phantom read)

     Also I need to mention that, innodb mysql of the mvcc has helped us solve the problem of phantom read, follow me explain in detail for everyone mvcc.

Third, the issue of things will have different levels of isolation

 mysql default isolation level: Repeatable Read (repeatable-read)

Isolation Levels Dirty read        Unrepeatable degree Magic Reading     
Uncommitted Read (read-uncommitted) Yes Yes Yes
Read Committed (read-committed) no Yes Yes
Repeatable Read (repeatable-read) no no Yes
Serializable (Serializable) no no no

 

 

 

 

 

Fourth, the isolation level detailed example

 

1, Uncommitted Read (read-uncommitted) - Dirty read

#首先,修改隔离级别
set tx_isolation='READ-UNCOMMITTED';
select @@tx_isolation;
+------------------+
| @@tx_isolation   |
+------------------+
| READ-UNCOMMITTED |
+------------------+

#事务A:启动一个事务
start transaction;
select * from tx;
+------+------+
| id   | num  |
+------+------+
|    1 |    1 |
|    2 |    2 |
|    3 |    3 |
+------+------+

#事务B:也启动一个事务(那么两个事务交叉了)
       在事务B中执行更新语句,且不提交
start transaction;
update tx set num=10 where id=1;
select * from tx;
+------+------+
| id   | num  |
+------+------+
|    1 |   10 |
|    2 |    2 |
|    3 |    3 |
+------+------+

#事务A:那么这时候事务A能看到这个更新了的数据吗?
select * from tx;
+------+------+
| id   | num  |
+------+------+
|    1 |   10 |   --->可以看到!说明我们读到了事务B还没有提交的数据
|    2 |    2 |
|    3 |    3 |
+------+------+

#事务B:事务B回滚,仍然未提交
rollback;
select * from tx;
+------+------+
| id   | num  |
+------+------+
|    1 |    1 |
|    2 |    2 |
|    3 |    3 |
+------+------+

#事务A:在事务A里面看到的也是B没有提交的数据
select * from tx;
+------+------+
| id   | num  |
+------+------+
|    1 |    1 |      --->脏读意味着我在这个事务中(A中),事务B虽然没有提交,但它任何一条数据变化,我都可以看到!
|    2 |    2 |
|    3 |    3 |
+------+------+

 

2、读已提交(read-committed)-- 不可重复读

#首先修改隔离级别
set tx_isolation='read-committed';
select @@tx_isolation;
+----------------+
| @@tx_isolation |
+----------------+
| READ-COMMITTED |
+----------------+

#事务A:启动一个事务
start transaction;
select * from tx;
+------+------+
| id   | num  |
+------+------+
|    1 |    1 |
|    2 |    2 |
|    3 |    3 |
+------+------+

#事务B:也启动一个事务(那么两个事务交叉了)
       在这事务中更新数据,且未提交
start transaction;
update tx set num=10 where id=1;
select * from tx;
+------+------+
| id   | num  |
+------+------+
|    1 |   10 |
|    2 |    2 |
|    3 |    3 |
+------+------+

#事务A:这个时候我们在事务A中能看到数据的变化吗?
select * from tx;
+------+------+                
| id   | num  |                
+------+------+                
|    1 |    1 |--->并不能看到!  
|    2 |    2 |                
|    3 |    3 |                
+------+------+                
                               
#事务B:如果提交了事务B呢?         
commit;                        
                               
#事务A:                         
select * from tx;
+------+------+
| id   | num  |
+------+------+
|    1 |   10 |----------------->相同的select语句,两次查询结果不一样
|    2 |    2 |
|    3 |    3 |
+------+------+

 

3、可重复读repeatable-read)-- 幻读

#首先,更改隔离级别
set tx_isolation='repeatable-read'; select @@tx_isolation; +-----------------+ | @@tx_isolation | +-----------------+ | REPEATABLE-READ | +-----------------+ #事务A:启动一个事务 start transaction; select * from tx; +------+------+ | id | num | +------+------+ | 1 | 1 | | 2 | 2 | | 3 | 3 | +------+------+ #事务B:开启一个新事务(那么这两个事务交叉了)
       在事务B中更新数据,并提交 start transaction; update tx set num=10 where id=1; select * from tx; +------+------+ | id | num | +------+------+ | 1 | 10 | | 2 | 2 | | 3 | 3 | +------+------+ commit; #事务A:这时候即使事务B已经提交了,但A能不能看到数据变化? select * from tx; +------+------+ | id | num | +------+------+ | 1 | 1 | --->还是看不到的!(这个级别2不一样,也说明级别3解决了不可重复读问题) | 2 | 2 | | 3 | 3 | +------+------+ #事务A:只有当事务A也提交了,它才能够看到数据变化 commit; select * from tx; +------+------+ | id | num | +------+------+ | 1 | 10 | | 2 | 2 | | 3 | 3 | +------+------+

 

4、可串行化(serializable)

 #首先修改隔离界别
set tx_isolation='serializable';
select @@tx_isolation;
+----------------+
| @@tx_isolation |
+----------------+
| SERIALIZABLE   |
+----------------+

#事务A:开启一个新事务
start transaction;

#事务B:在A没有commit之前,这个交叉事务是不能更改数据的
start transaction;
insert tx values('4','4');
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
update tx set num=10 where id=1;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

 

参考文章

    https://www.cnblogs.com/snsdzjlz320/p/5761387.html

 

Guess you like

Origin www.cnblogs.com/kukudexin/p/10965646.html