今天小伙伴问了一个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. 调整事务的隔离级别

最新文章

  1. 【转】XenServer架构之XAPI的调用流程
  2. WMI使用
  3. Android:如何从堆栈中还原ProGuard混淆后的代码
  4. linux64需要增加的依赖库
  5. uva 1639--精度处理方法之取对数(uva 1639)
  6. 跨应用Session共享
  7. C++ 临时对象
  8. Android项目svn代码管理问题[转]
  9. HDU 1013.Digital Roots【模拟或数论】【8月16】
  10. 关于synchronized
  11. Puppeteer 应用容器化
  12. linux 目录/sys 解析
  13. python_06 函数、全局变量与局部变量、函数递归
  14. http 概念
  15. 浅谈压缩感知(二十二):压缩感知重构算法之正则化正交匹配追踪(ROMP)
  16. Day9作业及默写
  17. codeforces 877e
  18. python 数据类型二 (列表和元组)
  19. 转:修改ETM,用Ogre实现《天龙八部》地形与部分场景详解
  20. 大型运输行业实战_day03_2_使用ajax将请求页面与请求数据分离

热门文章

  1. Mysql 的变量
  2. 09_控制线程_线程睡眠sleep
  3. POJ 2127 Greatest Common Increasing Subsequence -- 动态规划
  4. OpenJudge 2766 最大子矩阵
  5. 鸟哥私房菜笔记:Iptables:数据包过滤软件
  6. dynamic 动态获取object数据
  7. centos 7.0 mono&Jexus V5.5.3安装
  8. GroupBox 重绘圆角边框和文字
  9. MAC 上找不到.bash_profile或者ect/profile该怎么办?
  10. eclipse Ctrl +左键查看源代码Source not found