解决超发现象的方法(有两种方法)

解决超发现象的方法(有两种方法)

1、悲观锁

​ 悲观锁是一种利用数据库内部机制提供的锁的方法,也就是对更新的数据加锁,这样在并发期间一旦有一个事务持有了数据库记录的锁,其他的线程将不能再对数据进行更新了。

​ 修改SQL语句,加入“for update”,意味着将持有对数据库记录的行更新锁(因为这里使用主键查询,所以只会对行加锁。如果使用的是非主键查询,要考虑是否对全表加锁的问题,加锁后可能引发其他查询的阻塞),那就意味着在高并发的场景下,当一条事务持有了这个更新锁后才能往下操作,其他的线程如果要更新这条记录都需要等待,这样就不会出现超发现象引发的数据不一致的问题了。

但是,悲观锁会导致系统性能下降。对于悲观锁来说,当一条线程抢占了资源后,其他的线程将得不到资源,那么这个时候,CPU 就会将这些得不到资源的线程挂起,挂起的线程也会消耗 CPU 的资源。由于高并发环境下的频繁挂起线程和恢复线程,导致CPU频繁切换线程上下文,从而使CPU资源得到了极大的消耗,造成了性能不佳的问题。悲观锁也称独占锁

1)、具体步骤如下:
(1)、环境配置、业务逻辑和“抢红包超发现象一致”,只是在它基础上加上一些语句和语法
(2)、RedPacket.xml
<!-- 查询红包具体信息   加锁语句 -->
<select id="getRedPacketForUpdate" parameterType="long"
	resultType="com.ssm.chapter22.pojo.RedPacket">
	select id, user_id as userId, amount, send_date as
	sendDate, total,
	unit_amount as unitAmount, stock, version, note
	from
	T_RED_PACKET where id = #{id} for update
</select>
(3)、DAO层(RedPacket.java)
/***
 * 使用for update语句加锁.
 * @param id ——红包id
 * @return 红包信息
 */
public RedPacket getRedPacketForUpdate(Long id);
(4)、Service层(RedPacketService.java接口)
/***
 * 使用for update语句加锁.
 * @param id ——红包id
 * @return 红包信息
 */
public RedPacket getRedPacketForUpdate(Long id);
(5)、接口实现类RedPacketServiceImpl.java
@Override
@Transactional(isolation=Isolation.READ_COMMITTED,propagation=Propagation.REQUIRED)
public RedPacket getRedPacketForUpdate(Long id) {
	return redPacketDao.getRedPacketForUpdate(id);
}
(6)、接口实现类UserRedPacketServiceImpl.java

在UserRedPacketServiceImpl.java里grapRedPacket()方法中,

把RedPacket redPacket = redPacketDao.getRedPacket(redPacketId);改为

RedPacket redPacket=redPacketDao.getRedPa

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值