MySQL并发更新数据时的处理方法


     执行SELECT语句时没有加锁,只有在执行UPDATE时才进行加锁的。所以才会出现并发操作时的更新数据不一致

a = SELECT * FROM table1 WHERE id=1;
UPDATE table1 SET num = a.num + 1 WHERE id=1; 

  解决的方法可以有2种:

通过事务显式的对SELECT进行加锁
使用乐观锁机制

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

SELECT ... LOCK IN SHARE MODE       #共享锁,其它事务可读,不可更新
SELECT ... FOR UPDATE               #排它锁,其它事务不可读写

  默认情况下SELECT语句是不会加锁的。并且对于上面提到的场景,必须使用排它锁。另外,上面的2种语句只有在事务之中才能生效,否则不会生效。在MySQL命令行使用事务的方式如下:

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操作。(重新查询记数据行,再次使用新的版本号更新数据)
  


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM