mysql关于数据库事务隔离级别测试(包含实例测试语句,及测试结果对比)

1、知识点;

事务的四大特性 ACID ;

 原子性(Atomic):事务是一个整体(无论在该事务中操作任何CRUD),要不全部执行,要不全部不执行。(数据库能够进行操作的最小的逻辑单元)

一致性(Consistent):组成一个事务的操作是CRUD,要么全部成功,要么全部失败(类似原子性的后续补充)。

隔离性(Insulation):事务之间的隔离(比如:AB两个事物,并发时,A事务在读取数据时,仅能读取B事务操作之间的数据,或是B事务操作之后的数据,无法读取操作中的数据)

持久性(Duration):事务完成后对数据的修改时永久的。

事务的四大隔离级别;

读未提交(read uncommitted):一个事务可以读到另一个事务未提交的结果(所有的问题均会出现(脏读、不可重复读、幻读))

读提交(read committed ):只有一个事务被提交后,其更新结果才能被其他事务读取到(出现问题(不可重复读、幻读),解决(脏读))

可重复读(repeatable read):在一个事务中,对于同一份数据的读取结果总是相同的,无论是否有其他事务对这份数据进行操作,以及这个事务是否提交。(解决(脏读、不可重复读、幻读)) (mysql默认级别)

序列化(serializable):事务串行化执行,隔离级别最高,牺牲了系统的并发性。可以解决并发事务的所有问题。

不同隔离级别可能导致的问题:脏读、不可重复读,幻读

并发问题汇总:

脏读:一个事务读取到另一个事务未提交的数据。

不可重复读:一个事务在不同时刻读取到不同的数据。

幻读:一个事务在读取数据后,(另一个事务执行添加操作后)。由于不可重复读的问题解决,所以该事务读取不到新添加的数据,所以在添加同样主键的数据时会报错,

2、实例数据及测试

备注:建议开始前先将会话的自动提交关闭:

命令:$>set session autocommit = 0;  -- 关闭会话事务的自动提交

$>show session variables like "autocommited" ;  -- 查看事务提交自动化状态。

1>读未提交:最低的隔离界别,三大问题均存在(脏读、不可重复读、幻读)

实现简述:A会话 (repeatable  read )、B会话(read uncommitted) 。A会话中创建事务,然后修改数据,但不提交,B会话可以读到A未提交的数据:  以下按操作顺序依次执行。

A会话:

查看A的会话界别

使用数据库

开启事务

修改数据,但并未提交

B会话(A不关闭,重新启动一个会话);

查看当前隔离界别

不修改隔离界别,发现数据并未读取到未提交的数据。

 设置隔离界别为读未提交

读取到未提交的数据。

2>读提交(存在问题:不可重复读)

实现简述:在1的基础上,修改B会话的隔离界别为read commited ,发现脏读会被解决(及读取不到A会话未提交的数据)。

B会话:

设置隔离界别为读已提交。脏读被解决。

问题:可重复读。

问题描述:A会话中,在B会话对数据进行第一次查询后,对该数据进行修改并提交 。B会话再对该数据进行查询,发现第二次和

第一次查询出来的数据不一致。

B会话:

设置隔离界别为读提交,开启事务,第一次查询数据。

A会话

查询数据、开启事务。修改数据。

提交数据。

查看数据已修改。

B会话

两次查询数据不一致。

3>可重复读

问题解决描述:在2的基础上,设置B会话的隔离界别为repeatable read,发现B会话再第一二次读取的数据一致。

B会话:

设置隔离界别为可重复读

A会话

修改数据

B会话

发现在同一个事物中两次读取数据一致

提交事务后,读取到修改后的数据。

问题描述:幻读,A会话,查询数据时,发现主键id的数值到1,然后B开启事务,添加一个主键id为2的数据,之后提交数据。然后A会话,提交主键是2的数据,发现报(主键id为2的数据已存在)。但A缺没读取到,出现了幻读。

A会话

B会话

创建数据

A会话

第二次查询数据(不可重复读)后,添加报错,已存在 A会话出现幻读。

4>序列化(串行化(悲观锁))(锁行) (读占写锁)

问题描述:设置A会话为串行化(serializable),然后创建事务,查询users表后,在B会话中创建事务,往users表中添加数据发现被塞住了,只要A会话中的事务提交了,B会话才可添加成功(同样,A创建事务后(不查询users表),B创建事务后,添加数据到users表中(可成功,不提交事务,然后A会话查询users表,发现被塞住了,只有B会话的事务提交后,才可提交成功!)。避免了幻读,但很影响性能、

A会话

设置事务为串行化

创建事务查询users表

B会话

创建事务,可查询users表,但添加数据时被塞住

A会话提交数据

B会话中的添加操作执行(由于本机操作时间慢了,所以超时,速度快点会执行,然后B会话提交事务即可)。

猜你喜欢

转载自blog.csdn.net/weixin_39435629/article/details/80167928