mysql 事务隔离级别 xa_MySQL事务隔离级别-案例驱动

SQL92将事务隔离级别分为了4种,读未提交,读已提交,可重复读,可串行化。不同的隔离级别,对于数据的可见性不同,就会导致不同的正确性。事务的核心在于控制多个客户端在读写共享数据时候的并发问题。这篇文章通过实例研究隔离级别,我们将从读未提交开始,一步一步分析。

step1 创建表和基础数据

CREATE TABLE `traning`.`account` (

`id` INT NOT NULL AUTO_INCREMENT COMMENT '主键id',

`uid` INT NOT NULL COMMENT '用户uid',

`amount` INT NOT NULL COMMENT '金额',

PRIMARY KEY (`id`));

INSERT INTO `traning`.`account` (`uid`, `amount`) VALUES ('1', '1000');

INSERT INTO `traning`.`account` (`uid`, `amount`) VALUES ('2', '2000');

step2 修改隔离级别

场景1 读未提交导致脏读

Client1:SET GLOBAL TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

Client2:SET GLOBAL TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

关闭会话重新进入MySQL客户端。

Client2:show variables like 'transaction_isolation';

Client1: start TRANSACTION;

Client2: start TRANSACTION;

Client2: select amount from account where uid=1; (1000)

update account set amount=amount-500 where uid=1;

Client1: select amount from account where uid=1; (读到别人没提交事务:500)

-- update account set amount=(amount+100) where uid=1;(数据被锁,不能更新)

Client2: rollback;(Client1再次读到的是1000,但是没有读)

-- Client1: select amount from account where uid=1; (500)

Client1: update account set amount=(500+100) where uid=1; (读到旧数据去进行更新操作,导致账户丢失500)

场景2 读已提交解决脏读问题

Client1:SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;

Client2:SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;

关闭会话重启。

Client1:start TRANSACTION;

Client2:start TRANSACTION;

Client2: select amount from account where uid=1; (1000)

update account set amount=amount-500 where uid=1; (500)

Client1:select amount from account where uid=1 (读取不到别人没提交的事务:1000);

update account set amount=1000-500 where uid=1;(数据被锁不能更新)

Client2: rollback;

Client1: update account set amount=(1000+100) where uid=1;

Client1: commit;

场景3 读已提交导致不可重复读问题

Client1:SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;

Client2:SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;

关闭会话重启。

Client1:start TRANSACTION;

Client2:start TRANSACTION;

Client1:select amount from account where uid=1; (1000);

Client2:update account set amount=amount-100 where uid=1;

Client2: commit;

Client1: select amount from account where uid=1(amount=900,发现自己钱少了100);

场景4 可重复读解决不可重复读问题

Client1:SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ;

Client2:SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ;

Client1:start TRANSACTION;

Client2:start TRANSACTION;

Client2: select amount from account where uid=1;(1000)

Client1:select amount from account where uid=1; (1000);

Client2:commit;

Client1:select amount from account where uid=1;(amount=1000);

场景5 可重复读导致幻读问题

Client1:SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ;

Client2:SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ;

Client1:start TRANSACTION;

Client2:start TRANSACTION;

Client2: select amount from account ; (2行数据)

Client1:select amount from account ; (2行数据);

Client2:INSERT INTO traning.account (uid, amount) VALUES ('3', '3000');

Client2:commit;

Client1:select amount from account ;(3条数据);

Clinet1 :update account set amount=1 where id=3(Client读不到但是可以更新);

Clinet1 :select amount from account ;(4条数据-phantom read here!!!!影响了client1的判断和数据);

Clinet1 :commit;

场景6 可序列化解决幻读问题

Client1:SET GLOBAL TRANSACTION ISOLATION LEVEL SERIALIZABLE;

Client2:SET GLOBAL TRANSACTION ISOLATION LEVEL SERIALIZABLE;

Client1:start TRANSACTION;

Client2:start TRANSACTION;

Client2: select amount from account ; (2行数据)

Client1:select amount from account ; (2行数据);

Client2:INSERT INTO traning.account (uid, amount) VALUES ('3', '3000'); (插入不进去,数据被锁)

Lock wait timeout exceeded; try restarting transaction

以下是整理的图:

cc8e29250e13a2b155b489f503737f50.png

当然还有第一类丢失更新(脏写)和第二类丢失更新,第一类丢失更新永远不会发生,第二类丢失更新会在RU和RC情况下发生。

这是完整的图

包含了更多的隔离级别和可能发生数据异常情况:

895a152d2f44f01f4d83ac22d1db5cd8.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值