简介
最近公司在做团购这块的一个商品的促销活动,在创建促销的时候发现只能有一个用户进行修改和编辑,如果其他用户操作同一个促销活动就会出现数据不一致,这也就是我们经常遇到的多人同时操作的问题,下面我将详细介绍关于这块我们的解决方案
出现数据不一致的现象通常分为两种:1.覆盖更新 2.脏读
关于这类问题一般会考虑到用数据库锁的机制来解决
数据库锁分为乐观锁和悲观锁
乐观锁
乐观锁并不锁住任何东西,而是在提交事务时检查自己上次读取这条记录后,是否有其他事务修改了这条记录,如果没有则提交,如果被修改了则回滚。如果并发的可能性并不大,那么锁定策略带来的性能消耗是非常小的
悲观锁
与乐观锁相比,悲观锁则是一把真正的锁了,它通过SQL语句“select for update”锁住数据,这时如果其他事务来更新时会等待,悲观锁会锁住整张表,性能较低,导致其他的事务不能访问
实例介绍
接下来对于这块我采用的是乐观锁的方案,关于实现乐观锁有三种方式:
1.是为数据表增加一个version字段,每次事务开始时,取出version,在提交事务时,检查version是否有变化
如果没有变化提交事务时将version + 1,SQL差不多是这样:
UPDATE t_promotion
set version = version + 1
where promotionid = ?
and version = ?
2.是为数据表增加一个时间戳字段,然后通过比较时间戳检查该数据是否被其他事务修改过。
3.是检查对应的字段的值有没有变化
这里采用第一种方式 ,第二种跟第一种很类似 第三种性能不高
总结笔记
解决多人同时操作问题解决方案:
1.采用数据库锁的机制
乐观锁的实现方案:
就是在提交事务时检查自己上次读取这条记录后,是否有其他事务修改了这条记录,如果没有则提交,如果被修改了则回滚
一般有三种方式实现乐观锁:
(1).是为数据表增加一个version字段,每次事务开始时,取出version,在提交事务时,检查version是否有变化
如果没有变化提交事务时将version + 1,SQL差不多是这样:
UPDATE T_IRS_RESOURCE
set version = version + 1
where resource_id = ?
and version = ?
(2).是为数据表增加一个时间戳字段,然后通过比较时间戳检查该数据是否被其他事务修改过。
(3).是检查对应的字段的值有没有变化。
ibatis实现乐观锁解决方案的实现原理
使用数据版本(Version)记录机制实现,这是乐观锁最常用的一种实现方式。何谓数据版本?即为数据增加一个版本标识,一般是通过为数据库表增加一个数字类型的 “version” 字段来实现。当读取数据时,将version字段的值一同读出,数据每更新一次,对此version值加一,当我们提交更新的时候,判断数据库表对应记录的当前版本信息与第一次取出来的version值进行比对,如果数据库表当前版本号与第一次取出来的version值相等,则予以更新,否则认为是过期数据
举例:
那么为了使用乐观锁,我们首先修改t_goods表,增加一个version字段,数据默认version值为1。
<update id="updateGoodsUseCAS" parameterType="Goods">
<![CDATA[
update t_goods
set status=#{status},name=#{name},version=version+1
where id=#{id} and version=#{version}
]]>
</update>