MySQL事务隔离级别

-- SERIALIZABLE serializable 序列化 ;一个个事务排成序列的形式。事务一个挨一个执行,等待前一个事务执行完,后面的事务才可以顺序执行
-- REPEATEABLE READ repeatable read 可重复读 ;
-- READ COMMITED read committed 提交的可读;(oracle默认)
-- READ UNCOMMITED read uncommitted 未提交的可读;(mysql 默认)别的事务可以查看的到使用 当前事务还没提交的 数据;会 脏读,幻读,不可重复读。

mysql 的serializable序列化隔离级别所导致问题的模拟

首先,创建一张表来通过对该表的操作来实现

CREATE TABLE `software` (
`sid` int(11) DEFAULT NULL,
`version` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

写入一条记录 insert into (sid,version) values (1,1); 

同事开启两个事务  事务A 事务B;

1,创建第一个mysql连接,设置当前会话的隔离级别为 serializable;开启一个事务A,查看software表中有一条记录;

mysql串行化的隔离级别 mysql 串行化_mysql串行化的隔离级别

 2.再创建一个新mysql连接,设置当前会话的隔离级别为 serializable;开启一个事务B,查看software表中有一条记录;

mysql串行化的隔离级别 mysql 串行化_mysql_02

 3.回到事务A的mysql会话中执行 向software表插入一条数据;

mysql串行化的隔离级别 mysql 串行化_mysql_03

 此时,事务A会执行失败,提示超时了。失败原因是,因为事务B也是serializable隔离级别的,并且还没被提交。serializable隔离级别的多个事务不可以同事对同一张表修改!

4.事务B执行commit;

mysql串行化的隔离级别 mysql 串行化_序列化_04

 5.事务A重新执行插入一条记录:insert into software (sid,version) values (2,1);

mysql串行化的隔离级别 mysql 串行化_mysql_05

 

mysql串行化的隔离级别 mysql 串行化_mysql串行化的隔离级别_06

 

事务A此时执行成功了!

结论:serializable隔离级别的多个事务不可以同事对同一张表修改!

另外:当事务A执行的过程中如果对software表有update操作,事务B也不可以对事务A用到的表software表进行查询操作!

1.事务A与事务B同时都只对software表做查询 select 操作,不会导致死锁,可以查询出结果!

同时开启事务A,事务B,然后执行查询操作

1)事务A,

mysql串行化的隔离级别 mysql 串行化_mysql串行化的隔离级别_07

2)事务B,

mysql串行化的隔离级别 mysql 串行化_mysql串行化的隔离级别_08

3)事务A,

mysql串行化的隔离级别 mysql 串行化_mysql_09

4)事务B,

mysql串行化的隔离级别 mysql 串行化_mysql_10

2.事务A与事务B,都对software表做了查询操作,则事务A或者事务B不可以对software做修改,插入的操作了,因为会出现死锁的问题!

同时开启事务A ,事务B ;然后执行查询操作!

1)事务A

mysql串行化的隔离级别 mysql 串行化_mysql串行化的隔离级别_08

2)事务B

mysql串行化的隔离级别 mysql 串行化_mysql串行化的隔离级别_08

 

3)事务A

mysql串行化的隔离级别 mysql 串行化_mysql串行化的隔离级别_13

4)事务B

mysql串行化的隔离级别 mysql 串行化_mysql串行化的隔离级别_14

 5)事务A

mysql串行化的隔离级别 mysql 串行化_mysql串行化的隔离级别_15

此时事务A对software执行update 或者 insert 操作 都会失败, serializable 序列化 隔离级别,会造成表级锁,对所有的记录都不可以修改!

总结:在SERIALIZABLE级别下,不会使用mysql的mvcc机制,而是在每一个select请求下获得读锁,在每一个update操作下尝试获得写锁。

只有当事务A将对表software的update操作,insert操作 commit之后, 事务B才能看到 事务A对表作出的修改!