准备工作:

1.修改事务的提交方式,从自动提交修改为手动提交,修改之后重启数据库服务。

[mysqld]
skip-grant-tables
transaction-isolation = READ-UNCOMMITTED
autocommit = 0
# The TCP/IP Port the MySQL Server will listen on
port=3306

2.修改全局事务隔离级别,修改之后重启数据库服务,就可以看到数据库隔离级别被修改

[mysqld]
skip-grant-tables
transaction-isolation = READ-UNCOMMITTED
# The TCP/IP Port the MySQL Server will listen on
port=3306

3.验证read-uncommitted数据库事务隔离级别。如下图所示,sessionA仅仅是修改的数据,但是事务还没有提交,sessionB就能够查出来了。这就造成了“脏读”,一般数据库不使用这种隔离机制。

当事务回滚之后,sessionB查出来的数据又还原了。

4.验证read-committed数据库事务隔离级别。如下图所示,sessionA仅仅是修改的数据,但是事务还没有提交,此时sessionB查询出来的数据还没有改变,表明避开了“脏读”,一般数据库默认都使用这种隔离机制。但是mysql并不是默认使用的这种数据库事务隔离机制

 

在当sessionA中的事务提交之后,sessionB中再查询一次,会发现结果已经改正过来了。本来这种情况是比较合理的,因为sessionB查询出来的数据时sessionA提交之后的数据,属于已经持久化的实时数据。但是也造成了sessionB中前后两次查询结果不一致的现象,这种现象叫做“不可重复读”。所以read-committed解决了脏读,但是没有解决不可重复读

5.验证repeatable-read数据库事务隔离级别。如下图所示,sessionA修改了数据,并且事务已经提交,此时即使sessionA的事务提交了,sessionB查询出来的数据并没有改变。这种情况下是解决了不可重复读,对于sessionB在同一个事务中,前后查询结果没有发生改变。

 

只有sessionB的事务提交了之后,才能查询都持久化的数据,如下图所示

但是这里又会出现一种新的情况,叫做幻读。比如sessionB的事务中添加了一条记录并提交之后,在sessionA中在查询所有记录,却发现两次结果都不同。sessionA可能会比较困扰,因为自己没有做插入数据的操作,却多了一条数据。感到出现了幻觉。

5.要解决这种幻觉,需要引入serializable数据库事务隔离级别。如下图所示,sessionA修改了数据,只要有sessionA的事务在运行中还未提交,那么其他事务操作都必须等待。

Serializable 是最高的事务隔离级别,在该级别下,事务串行化顺序执行,可以避免脏读、不可重复读与幻读。但是这种事务隔离级别效率低下,比较耗数据库性能,一般不使用。