当前位置:首页 » 编程语言 » java数据库加锁

java数据库加锁

发布时间: 2025-02-15 01:34:14

1. java如何实现对Mysql数据库的行锁

下面通过一个例子来说明
场景如下:
用户账户有余额,当发生交易时,需要实时更新余额。这里如果发生并发问题,那么会造成用户余额和实际交易的不一致,这对公司和客户来说都是很危险的。
那么如何避免:
网上查了下,有以下两种方法:
1、使用悲观锁
当需要变更余额时,通过代码在事务中对当前需要更新的记录设置for update行锁,然后开始正常的查询和更新操作
这样,其他的事务只能等待该事务完成后方可操作
当然要特别注意,如果使用了Spring的事务注解,需要配置一下:

<!-- (事务管理)transaction manager, use JtaTransactionManager for global tx -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 使用annotation定义事务 -->
<tx:annotation-driven transaction-manager="transactionManager" />

在指定代码处添加事务注解

@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中的锁定方式,实际测试该方法确实可以有效控制,不过在大并发量的情况下,可能会有性能问题吧
<select id="getLock" resultMap="BaseResultMap" parameterType="java.lang.Long">
<![CDATA[
select * from user_balance where id=#{id,jdbcType=BIGINT} for update;
]]>
</select>

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}

这是一种不使用数据库锁的方法,解决方式也很巧妙。当然,在大量并发的情况下,一次扣款需要重复多次的操作才能成功,还是有不足之处的。不知道还有没有更好的方法。

热点内容
android动态添加fragment 发布:2025-09-24 23:06:36 浏览:778
java密钥生成 发布:2025-09-24 23:01:25 浏览:435
电脑读不出加密u盘 发布:2025-09-24 22:46:46 浏览:742
图形界面安装linux 发布:2025-09-24 22:21:05 浏览:958
预编译一个网页程序的好处 发布:2025-09-24 22:12:38 浏览:884
荣耀热点密码是多少 发布:2025-09-24 21:59:19 浏览:227
龙珠d加密 发布:2025-09-24 21:53:52 浏览:55
什么软件下载安卓市场 发布:2025-09-24 21:26:40 浏览:321
发短信php 发布:2025-09-24 21:26:00 浏览:775
电脑是怎么存储数字的 发布:2025-09-24 21:00:24 浏览:777