新业务需要在事务中使用乐观锁,在 RR 下需要回滚重试整个事务,而 rc 只需要重试某一个更新,有必要改成 rc 吗,如何判断业务在满足什么条件下可以不依赖 rr ,是不是只要不依赖可重复读就行
|  |      1leopod1995      116 天前 RR 场景相当于在一个 transaction 中可以对一条读 sql 多次调用返回一致的结果,原理就是在一个 transaction 中生成了 snapshot 。一般不用 RC 的原因就是在一个事务中会重复调用同一条 sql 。 如果能保证一个 transaction 中没有重复 sql 的情况下,是可以替换的。 | 
|  |      2cubecube      116 天前 @leopod1995 根本不需要保证,随时都能改,oracle 默认是 rc ,用 oracle 的系统都好好的不是。rr 纯粹为了刷存在感。 | 
|      3Dorathea      116 天前 你都用乐观锁了, 那 RC 会比 RR 更合适吧, 毕竟你都觉得数据大概率不会冲突了 | 
|  |      4barnetime      116 天前  1 | 
|      5Georgedoe      116 天前 性能有瓶颈的时候吧 , 没瓶颈改了也没啥收益 | 
|  |      6857681664      116 天前 如果业务在一个事务中允许一个读出来的数据被其他事务更改,且不影响正常业务的逻辑就行。话说如果只是乐观锁,完全可以不用考虑 rr 还是 rc ,直接用 update 语句判断执行结果是不是更好。 | 
|      7iseki      116 天前 你不在乎多个请求查出的数据之间存在不一致的时候 | 
|      8iPisces77      115 天前 mysql 整体就是给 RR 设计的,其他数据库都是 RC,所以你改了也没啥影响 | 
|      10kanepan19      66 天前 @byerer  // @Transactional(rollbackFor = Exception.class,isolation = Isolation.READ_COMMITTED) public void addBalanceByVersion(Long id, BigDecimal amount) { //乐观锁 没有 for update long systemTime = System.currentTimeMillis(); boolean flag = false; while (System.currentTimeMillis() - systemTime < waitTime) { flag = updateBalanceCheckVersion(id, amount); if (flag) { break; } try { Thread.sleep(10); } catch (InterruptedException e) { throw new RuntimeException(e); } } if (!flag) { throw new BizException("加款超时,稍后再试"); } } 要么不用事务,要么就加上 isolation = Isolation.READ_COMMITTED 都用事务了 老老实实的 select for update 或者 update xx set balance = balance - amount . 如果要记录流水还是 行锁。 |