乐观锁使用经验一则

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

@Entity
@Table(name="tbl_gift")
public class Gift {
	...
	
	//乐观锁
	@Version
	private 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的情况下,这种重试的方法是没有作用的。

你可能感兴趣的:(spring,Hibernate,框架,Exchange)