读书人

乐观锁应用经验一则

发布时间: 2012-10-17 10:25:47 作者: rapoo

乐观锁使用经验一则
假设需要用乐观锁来实现一个物品数量增减操作的原子性,可以这样子做:(框架使用spring和hibernate)

@Entity@Table(name="tbl_gift")public class Gift {...//乐观锁@Versionprivate Long version;...}

@Transactional(readOnly=false, propagation=Propagation.REQUIRED)public void exchange(){    ...    修改gift的剩余数量(采用乐观锁);    ...}


以上这段代码在并发修改下会有2种报错(org.hibernate.StaleObjectStateException)的可能:
(1)函数内(提交事务前);
线程1开事务->读礼品id=1,得version=0 -> 改剩余数量和version -> 提交事务
线程2开事务->读礼品id=1,得version=0 ----------------------------------->改剩余数量和version(出错)

(2)函数外(提交事务后);
线程1开事务->读礼品id=1,得version=0 -> 改剩余数量和version -> 提交事务
线程2开事务->读礼品id=1,得version=0 -> 改剩余数量和version ------------>提交事务(出错)

添加重试:
@Transactional(readOnly=false, propagation=Propagation.REQUIRED)public void exchange(){    ...    修改gift的剩余数量(采用乐观锁);    ...}public void exchange2() throws Exception {try {exchange();} catch(org.hibernate.StaleObjectStateException e) {exchange();}}

注意:是使用一个没有事务的方法包住一个有事务的方法。此外,如果在使用OpenSessionInView的情况下,这种重试的方法是没有作用的。

读书人网 >软件架构设计

热点推荐