1 事务隔离级别
read-uncommitted
:脏读、不可重复度、幻读,均可出现。安全性低,性能高。read-committed
(oracle默认):不可重复度、幻读。避免了脏读。repeatable-read
(mysql默认):幻读。避免了脏读、不可重复度。serializable
:避免了脏读、不可重复度、幻读。安全性高,性能低。
2 脏读
开启两个窗口:
- 查询事务默认的隔离级别
select @@transaction_isolation;
- 设置隔离级别为
read-uncommitted
set session transaction isolation level read uncommitted;
- 开启事务
start transaction;
- 脏读就是读到了其他事务,未提交的数据。
read-uncommitted
。 - 查询数据的时候会有错误。
- 银行场景举例:
甲查询自己的银行卡余额本来只有0元,如果发生脏读,乙向甲转账100万,这时事务未提交,甲再去查询余额则变为100万,然后疯狂购物。这时,乙由于超过支付限额,无法转账100万,发生事务回滚,这时甲的钱会变成负数。没有钱也能买东西了。
3 不可重复度
- 设置事务隔离级别为
read-committed
set session transaction isolation level read committed;
3.1 解决了脏读的问题。
3.2 有不可重复度的问题
- 场景举例:
甲开启事务查看账户还有100元,这时乙开启事务,修改为减去100时,甲查看数据,没有脏读,并且还是100元,这是乙提交事务,则再次查看数据,要去花的时候发现钱没了。
4 幻读
- 设置隔离级别
set session transaction isolation level repeatable read;
4.1 没有脏读和不可重复读的问题
4.2 有幻读的问题
第一个事务,先查询id为2 的数据为空,第二个事务新增id为3的数据,并提交事务。新增id为3的数据报错,但是,查询id为3的数据不存在,这就是幻读。
5 serializable
设置事务隔离级别为serializable
,脏读、不可重复读、幻读的问题都不存在,但是性能最低。
set session transaction isolation level serializable;
串行化:事务并发时,A事务提交后,B事务才能提交。