乐观并发控制(乐观锁)和悲观并发控制(悲观锁)是并发控制主要采用的技术手段。
无论是悲观锁还是乐观锁,都是人们定义出来的概念,可以认为是一种思想。
悲观锁
https://www.hollischuang.com/archives/934
当我们要对一个数据库中的一条数据进行修改的时候,为了避免同时被其他人修改,最好的办法就是直接对该数据进行加锁以防止并发。
这种借助数据库锁机制在修改数据之前先锁定,再修改的方式被称之为悲观锁。
在数据库中,悲观锁的流程如下:
在对任意记录进行修改前,先尝试为该记录加上排他锁(exclusive locking)。
如果加锁失败,说明该记录正在被修改,那么当前查询可能要等待或者抛出异常。 具体响应方式由开发者根据实际需要决定。
如果成功加锁,那么就可以对记录做修改,事务完成后就会解锁了。
其间如果有其他对该记录做修改或加排他锁的操作,都会等待我们解锁或直接抛出异常。
悲观锁实现案例:
乐观锁
https://www.iteye.com/blog/chenzhou123520-1863407
乐观锁会认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会对数据是否冲突进行检测,
如果发现冲突了,则返回用户错误的信息,让用户决定如何去做。
有2种方式实现乐观锁:
加version版本号字段
version记录版本号,是乐观锁最常用的一种实现方式; 或者加时间戳字段(timestamp),这俩实现都一样。
何谓数据版本?即为数据增加一个版本标识,一般是通过为数据库表增加一个数字类型的 “version” 字段来实现。当读取数据时,将version字段的值一同读出,数据每更新一次,对此version值加一。当我们提交更新的时候,判断数据库表对应记录的当前版本信息与第一次取出来的version值进行比对,如果数据库表当前版本号与第一次取出来的version值相等,则予以更新,否则认为是过期数据。
乐观锁实现案例:
那么为了使用乐观锁,我们首先修改t_goods表,增加一个version字段,数据默认version值为1。
下单操作包括3步骤:
1.查询出商品信息
select (status, name, version) from t_goods where id=#{id}
2.根据商品信息生成订单
3.修改商品status为2
update t_goods
set status=2,version=version+1
where id=#{id} and version=#{version};