MySQL 事务

创作人 Leo


编辑时间 Wed Jan 15,2020 at 10:55


事务

事务用来保证一系列SQL操作的原子性

共享锁 select … lock in share mode 加入共享锁 S
排它锁 select … for update 排它锁 L
SS 共享,LL 互斥,LS 互斥

where 条件为主键或者唯一键会触发行锁,使用索引会触发区间锁或表锁,无任何索引触发表锁

脏读 数据 a=2 ,事务 T-a 更新数据 a=1 ,事务 T-b 读取事务 a=1 ,事务 T-a 回滚 a=2 ,导致事务 T-b 读取了被回滚的脏数据,我们称这种情况为脏读
幻读 事务 T-a 更新一批数据后,其他事务又提交了新的插入条目,导致 T-a 又读取到新的需要更新的数据。唯有表锁能够解决幻读问题
不可重复读 在同一事务中两次读到的数据不一致

锁区间

当我们通过 SELECT … FOR UPDATE 这样的语句对多个数据条目进行加锁,InnoDB 会对整个区间进行加锁。
比如你查询中包含了 where xx>10 … for update ,则一条 xx=20 的新值执行插入时会被阻塞,而且一条 where xx>20 … for update 也会被阻塞
触发锁区间需要查询语句用到了普通索引(Index),否则触发表锁

mysql 官方文档:gap & gap lock mysql

事务的隔离级别

常用sql语句:
show variables like ‘%isolation%’ ; 查看当前服务器默认隔离级别
set session transaction isolation level repeatable read; 设置当前会话事务隔离级别(还可以设置全局,下次事务,具体参见MySQL文档)

read uncommitted 会读取其他事物未提交的数据变更,该级别基本上不会使用,更不建议使用
该级别存在脏读,幻读,重复读问题

read committed
其他事务提交更新或插入数据会影响当前事务,造成幻读
存在幻读,重复读问题,可解决脏读问题

repeatable read
这是mysql默认的隔离级别,实现一致性读,在事务中读取第一次读取的快照,无锁查询的情况下不受其他事务的影响。
使用 MVCC(Mutil-Version Concurrency Control 多版本并发控制)实现,类似于乐观锁的一种实现方式
该隔离级别解决脏读和不可重复度问题,但是不能解决幻读问题
如果一个事务 A 更新了一个条目,而事务 B 也更新该条目,则 B 会处于阻塞中,等待 A 提交事务或者回滚事务。
存在幻读,解决重复读和脏读问题

serializable
序列化,跟 repeatable read 类似,不同点是在 autocommit 关闭的情况下(系统设置,或者开启事务) serializable 会隐式地将 SELECT 语句转换为 SELECT … LOCK IN SHARE MODE
不建议使用,应用上更多的会使用 repeatable read ,而且在其他的编程模型中也要尽量少使用隐式转换

mysql 官方文档:SET TRANSACTION Statement
mysql 官方文档:Transaction Isolation Levels


阅读:34
搜索
  • Linux 高性能网络编程库 Libevent 简介和示例 1887
  • Mac系统编译PHP7【20190929更新】 1732
  • Windows 安装Swoole 1543
  • Hadoop 高可用集群搭建 (Hadoop HA) 1426
  • Hadoop 高可用YARN 配置 1347
  • 小白鼠问题 1269
  • Hadoop Map Reduce 案例:好友推荐 1226
  • 自动化测试工具 Selenium 1090
  • GIT 分支管理 1007
  • 一致性哈希算法说明及PHP示例 961
简介
不定期分享软件开发经验,生活经验