@
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  . 如果要记录流水还是 行锁。