事务隔离级别

2019-07-29  本文已影响0人  何德何能者

更新用户金额伪代码

long start = System.currentTimeMillis();
long timeout = 3 * 1000L;
while(true) {
  if(获取分段分布式锁成功) {
   try {
      User user = getUser(id);
      Long beforeUpdateTime = user.getUpdateTime();
      user.setMoney(user.getMoney() + 10); // 给用户加钱
      int count = updateUser(user, beforeUpdateTime); // 乐观锁更新用户金额
      if(count > 0) {
        // 记录日志
      }else {
        // 没更新成功,继续尝试
      }
    }finally{
      boolean releaseLock = // 释放分布式锁
      if(!releaseLock) {// 抛出运行时异常}
    }
  }
  if(System.currentTimeMillis() - start >= time) {
     // 超时,抛出运行时异常
  }
}

以上是段用分布式锁和数据库乐观锁的方式更新用户金额;代码本身没什么问题,可是后期表现处理的却是出现很多超时处理失败回滚的现象;

经过缜密的分析发现,循环里getUser(id)获取的数据不是数据库最新的,导致update乐观锁更新失败; 原因跟数据库的事务隔离级别有关; 由于使用的是默认的隔离级别,这里mysq默认的事务隔离级别是REPEATABLE-READ ;即可重复读;
mysql一共提供四种隔离级别;

上一篇 下一篇

猜你喜欢

热点阅读