MySQL 事务
MySQL 事务
特性
ACID
如何实现?
1. 原子性
场景:1.事务提交但没有持久;2.事务没有提交
解决:redo处理事务提交但没有flush磁盘,undo处理执行部分操作
2. 隔离性
场景:事务之间修改相同数据
【隔离级别】
读取未提交
事务A:开启事务,—,---,读取a
事务B:开启事务,更新a
说明:事务A读取的数据a,是事务B修改过的,但是事务B没有commit
读取已提交
事务A:开启事务,—,---,—,---,读取a
事务B:开启事务,更新a,commit
说明:事务A读取的数据a,是事务B修改过的,且事务B已经commit
可重复读:insert可见,update不可见
事务A:开启事务,—,---,—,---,读取a
事务B:开启事务,更新a,commit
说明:事务B更新、commit,事务A仍然读取不到数据a的变更
事务A:开启事务,—,---,—,---,查询
事务B:开启事务,insert b,commit
说明:事务B insert、commit,事务A查询可以获取记录b
串行化
【并发问题】
脏读:读取未提交例子中,事务A读取到事务B更新的数据a,如果事务B回滚,则事务A读到的数据a的更新,属于脏数据。
不可重复读:读取已提交例子中,事务A读取到事务B更新并commit的数据a,如果在事务B提交前读取,值为a1,在事务B提交后读取到的值只能为a2,则称为不可重复读
幻读:可重读读例子中,事务A在事务B insert b前查询,有n条数据,在事务B insert b后查询,则有n+1条数据(包含记录b),属于幻读
丢失更新
第一类,场景:
事务A:开启事务,更新数据a,commit
事务B:开启事务,更新数据a,rollback
由于事务B rollback,撤销事务B的更新,同时撤销了事务A的更新(是否存在:由于X锁,不存在。即事务B的撤销与事务A的无关)
第二类,场景:
事务A:开启事务,更新数据a,commit
事务B:开启事务,更新数据a,commit
最终取值:A还是B?或者A和B的叠加?
如何解决?串行化生产中不存在,悲观锁或者乐观锁
悲观锁:
-- 读锁定
select * from tbl where user = 'A' for update;
-- 更新
update tbl set col = 'a1' where user = 'A';
乐观锁:
-- 读取version
select * from tbl where user = 'B';
-- 更新并判断version
update tbl set col = 'a2' and version = version +1
where user = 'B' and version = ${version};
或者CAS:
update tbl set col = 'a3' where user = 'C' and col = 'a1';
3. 持久性
场景:1.事务提交没flush;2.事务没有提交
解决:提交的事务,会redo;没有提交的事务,会undo
4. 一致性
事务日志
特点:顺序IO,减少磁盘寻道,效率高
redo log和undo log
参考
事务,https://zhuanlan.zhihu.com/p/43493165
https://www.zhihu.com/question/30272728
https://hit-alibaba.github.io/interview/Server/db/Transaction.html
https://blog.csdn.net/sun8112133/article/details/89853755
丢失更新,https://segmentfault.com/a/1190000012626590
https://www.cnblogs.com/-mrl/p/13093469.html
上一篇: php empty()函数详细
下一篇: 数据标号与代码标号
推荐阅读
-
MySQL5.7完全卸载步骤详解
-
概述MySQL统计信息
-
mysql 5.7以上版本安装配置方法图文教程(mysql 5.7.12mysql 5.7.13mysql 5.7.14)
-
MySQL常见内存不足启动失败的完美解决方法
-
随机生成八位优惠码并保存至Mysql数据库
-
Mysql5.7中使用group concat函数数据被截断的问题完美解决方法
-
Mysql5.7.17 winx64.zip解压缩版安装配置图文教程
-
MySQL SQL语句分析与查询优化详解
-
Windows 64 位 mysql 5.7以上版本包解压中没有data目录和my-default.ini及服务无法启动的快速解决办法(问题小结)
-
解决mysql ERROR 1045 (28000)-- Access denied for user问题