MySQL 的乐观并发控制Optimistic concurrency control
2015-11-05 00:33
621 查看
默认情况下, MySQL的Innodb事务隔离级别是重复读 repeatable read,
进行以下测试, 同时开两个session, S1 和 S2, 都将autocommit关掉
测试使用的是一张简单的表, 只有一行数据
01 - S1 执行 select * from t1; 看到1, 1, 0
02 - S2 执行 select * from t1; 看到1, 1, 0
03 - S2 执行 update t1 set v2=2, version=version+1 where v1=1 and version=0; (Affected rows: 1)
04 - S2 执行 select * from t1; 看到1, 2, 1
05 - S1 执行 select * from t1; 看到1, 1, 0 - 无变化
06 - S1 执行 update t1 set v2=2, version=version+1 where v1=1 and version=0; 被挂起, 一直等待
07 - S2 执行 commit; 第06步的S1查询结束, 显示(Affected rows: 0)
08 - S1 执行 select * from t1; 依然看到1, 1, 0
09 - S1 执行 commit;
10 - S1 执行 select * from t1; 看到1, 2, 1 - 这时候数据才更新
由此可以验证, 在 REPEATABLE-READ 的隔离级别下, 一个事务并不能觉察到事务外部的数据变化, 所有读取的数据自事务开始后就不变, 但是update类型的操作, 会受到事务外部数据变化的影响, 首先是如果同一行数据有外部事务未提交, 则当前操作需要排队, 其次是如果同一行数据已经被外界更改, 则update操作会受影响, 例如本例中 Affected rows: 0
由此可见, 通过形如 update t1 set v2=2, version=version+1 where v1=1 and version=0 的方式来做并发控制是可行的.
SELECT @@GLOBAL.tx_isolation, @@tx_isolation; REPEATABLE-READ REPEATABLE-READ
进行以下测试, 同时开两个session, S1 和 S2, 都将autocommit关掉
set autocommit=0;
测试使用的是一张简单的表, 只有一行数据
CREATE TABLE `t1` ( `v1` tinyint(2) NOT NULL DEFAULT '0', `v2` tinyint(2) NOT NULL DEFAULT '0', `version` mediumint(8) NOT NULL DEFAULT '0', PRIMARY KEY (`v1`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; row: 1 1 0
01 - S1 执行 select * from t1; 看到1, 1, 0
02 - S2 执行 select * from t1; 看到1, 1, 0
03 - S2 执行 update t1 set v2=2, version=version+1 where v1=1 and version=0; (Affected rows: 1)
04 - S2 执行 select * from t1; 看到1, 2, 1
05 - S1 执行 select * from t1; 看到1, 1, 0 - 无变化
06 - S1 执行 update t1 set v2=2, version=version+1 where v1=1 and version=0; 被挂起, 一直等待
07 - S2 执行 commit; 第06步的S1查询结束, 显示(Affected rows: 0)
08 - S1 执行 select * from t1; 依然看到1, 1, 0
09 - S1 执行 commit;
10 - S1 执行 select * from t1; 看到1, 2, 1 - 这时候数据才更新
由此可以验证, 在 REPEATABLE-READ 的隔离级别下, 一个事务并不能觉察到事务外部的数据变化, 所有读取的数据自事务开始后就不变, 但是update类型的操作, 会受到事务外部数据变化的影响, 首先是如果同一行数据有外部事务未提交, 则当前操作需要排队, 其次是如果同一行数据已经被外界更改, 则update操作会受影响, 例如本例中 Affected rows: 0
由此可见, 通过形如 update t1 set v2=2, version=version+1 where v1=1 and version=0 的方式来做并发控制是可行的.
相关文章推荐
- PLSQL-Developer数据库连接工具使用方法
- Oracle GoldenGate 异构平台同步(Mysql到Oracle)
- mysql-proxy主从服务架构下读写分离和负载均衡实现及原理
- 在线备份MySQL及远程copy到远程备份服务器shell脚本
- [MySQL FAQ]系列 — MySQL复制中slave延迟监控
- 1.5 使用Sqoop从HDFS导出数据到MySQL
- PL/SQL Developer记住用户名密码
- 通过操作系统进程找到top sql信息
- 【SQLYOG】SSH ERROR:UNABLE TO OPEN CONNECTION:GETHOSTBYNAME:UNKNOWN ERROR牵引出来的一系列问题
- SQLServer邮件异常监控
- 1.4 使用Sqoop从MySQL数据库导入数据到HDFS
- 8.12 Optimizing the MySQL Server 优化MySQL Server 优化
- MySQL双主高可用架构之MMM实战
- Navicat远程无法连接mysql问题解决(附MAC上NavicatPremium11.1.8破解中文版下载链接)
- Oracle11g,在SQL Developer里新建连接时出现错误的解决办法
- Oracle11g,在SQL Developer里新建连接时出现错误的解决办法
- Oracle SQL Developer 添加SQLServer 和Sybase 连接
- SQL Server 2016 CTP3 集成R语言安装配置手册
- oracle 11g SQL Developer instead of isqlplus
- 导入数据时报错: MySQL server has gone away