UPDATE是否会加锁?

SQL语句为如下时,是否会加锁?

UPDATE table1 SET num = num + 1 WHERE id=1;

实际上MySQL是支持给数据行加锁(InnoDB)的,并且在UPDATE/DELETE等操作时确实会自动加上排它锁。只是并非只要有UPDATE关键字就会全程加锁,针对上面的MySQL语句而言,其实并不只是一条UPDATE语句,而应该类似于两条SQL语句(伪代码):

a = SELECT * FROM table1 WHERE id=1;UPDATE table1 SET num = a.num + 1 WHERE id=1;
  • 通过事务显式的对SELECT进行加锁
  • 使用乐观锁机制

SELECT显式

加锁对SELECT进行加锁的方式有两种,如下:

SELECT ... LOCK IN SHARE MODE  #共享锁,其它事务可读,不可更新SELECT ... FOR UPDATE    #排它锁,其它事务不可读写
SET AUTOCOMMIT=0; BEGIN WORK;  a = SELECT num FROM table1 WHERE id=2 FOR UPDATE;  UPDATE table1 SET num = a.num + 1 WHERE id=2; COMMIT WORK;

使用乐观锁

乐观锁是锁实现的一种机制,它总是会天真的认为所有需要修改的数据都不会冲突。所以在更新之前它不会给数据加锁,而只是查询了数据行的版本号(这里的版本号属于自定义的字段,需要在业务表的基础上额外增加一个字段,每当更新一次就会自增或者更新)。

在具体更新数据的时候更新条件中会添加版本号信息,

  • 当版本号没有变化的时候说明该数据行未被更新过,并且也满足更新条件,所以会更新成功。
  • 当版本号有变化的时候,则无法更新数据行,因为条件不满足,此时就需要在进行一次SQL操作。(重新查询记数据行,再次使用新的版本号更新数据)

实践

对 for update上锁进行一次实践一个student表,其中有一条数据

开启两个client

第一个开启事务后执行

select name from student where id = 1 for update;

第二个开启事务后执行相同的语句,发现该条数据被第一个事务上锁阻塞了

这时候第一个事务执行修改并commit;

第二个事务的select执行,发现阻塞了4秒多

小结

总的来说,这2种方式都可以支持数据库的并发更新操作。但具体使用哪一种就得看实际的应用场景,应用场景对哪种支持更好,并且对性能的影响最小。

更多相关文章

  1. ES6 变量声明,箭头函数,数组方法,解构赋值,JSON,类与继承,模块化练习
  2. 浅谈Java中Collections.sort对List排序的两种方法
  3. mybatisplus的坑 insert标签insert into select无参数问题的解决
  4. python起点网月票榜字体反爬案例
  5. Python list sort方法的具体使用
  6. python list.sort()根据多个关键字排序的方法实现
  7. android上一些方法的区别和用法的注意事项
  8. 《Android开发从零开始》——25.数据存储(4)
  9. android实现字体闪烁动画的方法

随机推荐

  1. 要成为一个专业的爬虫大佬,你还需要了解这
  2. 动画:深入浅出从根上理解 HTTP 缓存机制及
  3. 爬取3万景点,分析十一哪里人从众从人?
  4. 不使用 if-elif 语句,如何优雅地判断某个
  5. Python 3.9 性能优化:更快的 list()、dict
  6. Python小技巧:如何批量更新已安装的库?
  7. 大学历经几十个落地项目,小鹿教科书式经验
  8. 扫盲篇:实现一个简易的 webpack!
  9. Python 为什么不支持 i++ 自增语法,不提供
  10. “三本”大学,小鹿春秋招误入的坑!