数据库 一致性读&&当前读
今天小伙伴问了一个sql的问题:
update t set status=2 where id in(select id from t where status=1)
这个sql,在并发的情况下,会不会有问题?
假设:下面的讨论,数据库的事务隔离级别是read_committed
其实这个可以很容易测试一下,得出结论:存在丢失更新的问题。
先来理解两个概念:
1. 一致性读
当前的数据库产品级别都实现了多版本一致性,即MVCC,那么有了MVCC,数据库实现了读写互不阻塞的效果。
但为了达到read_committed事务隔离级别,以及语句级的读一致性,select语句需要构建一个版本,数据库会根据一个版本号,来构建。
比如oracle使用scn号,为了构建这个版本,产生的读,称为一致性读。
2. 当前读
数据库在写入的过程中,比如update,因为要验证constraint,冲突等,需要读到当前数据,包括没有commit的事务,这样就产生了当前读。
oracle中英文解释:
一致性读: Consistent read
当前读: Current read
而上面的这个语句,就存在了两种读取。
select: 会进行一致性读,
update:会进行当前读。
而在并发的情况下: 第二个update可能因为更新到同一行(其他更新本行的事务未提交),而被阻塞。
当另一个事务提交后,第二个update会再次构建当前读,会把status从2再次更新成2.
如何避免:
1. 更改语句:
update t set status=2 where id in(select id from t where status=1) and status=1;
2. 调整事务的隔离级别
最新文章
- 【转】XenServer架构之XAPI的调用流程
- WMI使用
- Android:如何从堆栈中还原ProGuard混淆后的代码
- linux64需要增加的依赖库
- uva 1639--精度处理方法之取对数(uva 1639)
- 跨应用Session共享
- C++ 临时对象
- Android项目svn代码管理问题[转]
- HDU 1013.Digital Roots【模拟或数论】【8月16】
- 关于synchronized
- Puppeteer 应用容器化
- linux 目录/sys 解析
- python_06 函数、全局变量与局部变量、函数递归
- http 概念
- 浅谈压缩感知(二十二):压缩感知重构算法之正则化正交匹配追踪(ROMP)
- Day9作业及默写
- codeforces 877e
- python 数据类型二 (列表和元组)
- 转:修改ETM,用Ogre实现《天龙八部》地形与部分场景详解
- 大型运输行业实战_day03_2_使用ajax将请求页面与请求数据分离
热门文章
- Mysql 的变量
- 09_控制线程_线程睡眠sleep
- POJ 2127 Greatest Common Increasing Subsequence -- 动态规划
- OpenJudge 2766 最大子矩阵
- 鸟哥私房菜笔记:Iptables:数据包过滤软件
- dynamic 动态获取object数据
- centos 7.0 mono&;Jexus V5.5.3安装
- GroupBox 重绘圆角边框和文字
- MAC 上找不到.bash_profile或者ect/profile该怎么办?
- eclipse Ctrl +左键查看源代码Source not found