悲观锁
按性质划分
- 共享锁:S锁,可进行读取数据,但事务没有提交前不能修改数据
- 排他锁:X锁,独占锁,其它事务不能在给它加锁了
- 更新锁:U锁,在修改操作的初始化阶段来锁定可能被修改的资源,避免使用共享锁造成的死锁
按作用范围
- 表级锁
- 行级锁
乐观锁
数据库不做加锁处理,数据提交时进行检测,若冲突则给用户错误信息让用户自行处理
乐观锁实现
提交数据时,先取出数据与第一次取出来的数据进行对比。
存在ABA问题:
数据A在被B修改N次后又变回A,结果一致不代表没问题。但可以用一个递增的版本号解决ABA问题或时间戳
注:高并发是常用的事情,总让用户感到失败是不合理的,所以还要减少乐观锁粒度
版本号
就是给数据增加一个版本标识,在数据库上就是表中增加一个version字段,每次更新把这个字段加1,读取数据的时候把version读出来,更新的时候比较version,如果还是开始读取的version就可以更新了,如果现在的version比老的version大,说明有其他事务更新了该数据,并增加了版本号,这时候得到一个无法更新的通知,用户自行根据这个通知来决定怎么处理,比如重新开始一遍。
时间戳
类似于版本号方式,只是通过时间戳来判断而已,注意时间戳要使用数据库服务器的时间戳不能是业务系统的时间。
待更新字段
和版本号方式相似,只是不增加额外字段,直接使用有效数据字段做版本控制信息,因为有时候我们可能无法改变旧系统的数据库表结构。假设有个待更新字段叫u_balance,先去读取这个u_balance(假设值为999),更新的时候去比较数据库中u_balance的值是不是我们期望的值(一开始读取的那个值),如果是就把我修改的u_balance的值更新到该字段,否则更新失败。
所有字段
使用所有字段做版本控制信息,只有所有字段都没变化才会执行更新。(很准确的检测,但是降低了程序运行的效率
本文来自博客园,作者:尾牙衣子,转载请注明原文链接:https://www.cnblogs.com/sunpan/p/14209897.html
