Java如何实现对Mysql数据库的行锁

1、使用悲观锁 当需要变更余额时,通过代码在事务中对当前需要更新的记录设置for update行锁,然后开始正常的查询和更新操作 这样,其他的事务只能等待该事务完成后方可操作 当然要特别注意,如果使用了Spring的事务注解,需要配置一下:复制代码 复制代码 在指定代码处添加事务注解复制代码@Transactional @Override public boolean increaseBalanceByLock(Long userId, BigDecimal amount) throws ValidateException { long time = System.currentTimeMillis(); //获取对记录的锁定 UserBalance balance = userBalanceDao.getLock(userId); LOGGER.info("[lock] start. time: {}", time); if (null == balance) { throw new ValidateException( ValidateErrorCode.ERRORCODE_BALANCE_NOTEXIST, "user balance is not exist"); } boolean result = userBalanceDao.increaseBalanceByLock(balance, amount); long timeEnd = System.currentTimeMillis(); LOGGER.info("[lock] end. time: {}", timeEnd); return result; }复制代码MyBatis中的锁定方式,实际测试该方法确实可以有效控制,不过在大并发量的情况下,可能会有性能问题吧 2、使用乐观锁 这个方法也同样可以解决场景中描述的问题(我认为比较适合并不频繁的操作): 设计表的时候增加一个version(版本控制字段),每次需要更新余额的时候,先获取对象,update的时候根据version和id为条件去更新,如果更新回来的数量为0,说明version已经变更 需要重复一次更新操作,如下:sql脚本 update user_balance set Balance = #{balance,jdbcType=DECIMAL},Version = Version+1 where Id = #{id,jdbcType=BIGINT} and Version = #{version,jdbcType=BIGINT}

你可能感兴趣的:(Java如何实现对Mysql数据库的行锁)