想必隔离级别一直是一个诸多程序员避而不谈的问题,对各种脏读、不可重复度、幻读的问题也是一知半解
我以库存扣减为例子大概来阐述rc rr对应的解决方案
RC级别
start transactionTA; start transactionTB; TA query store=100; TB query store=100; TB update set store=store-20 where sku=1 and store=100; affect 1; TA update set store=store-10 where sku=1 and store=100; affect 0;TA在执行后发现sku 1库存已经为80,所以不会有 affect 0,此时程序重新查询后 再进行 update便可执行成功
RR级别
在上述案例中,TB重新查询后store永远都是100,然而每次重试后永远都是affect 0;这时就需要重新开启事务来处理;
@Override @Retryable(value = BizsException.class)//重试 public Boolean updateBalance(Balance balance) throws BizsException { //查询数据 BalanceVO balanceVO = readCommitService.searchBalanceById(balance.getId()); Integer result = balanceDao.updateBalance(balanceVO); //发现通过乐观锁没有更新到数据则抛出异常驱动retryable重新调用接口 if (result < 1) { throw new BizsException(ResultEnum.BALANCE_OPERATE_ERROR); } return true; } //强制不启动事务 不指定可能外层嵌套事务后存在一些问题 ***如果隔离界别为rc级别无需此步*** @Transactional(propagation = Propagation.NOT_SUPPORTED) public BalanceVO searchBalanceById(Long balanceId) { return balanceDao.searchBalanceById(balanceId); }maven dependency
<dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> <version>1.2.2.RELEASE</version> </dependency>如果对此文章有任何疑问请联系本人qq:1808568908
