关于synchronized使用的问题汇总

当在@Transactional注解的方法上同时使用synchronized关键字,可能会导致事务未提交时重复执行,引发脏读问题。解决方案是将synchronized方法置于事务之外,通过一个不带事务的同步方法调用带有事务的服务层方法,确保事务提交后再执行下一次同步操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


因为是逐步积累,所以一开始遇到的问题也不会很多。

错1:在@Transactional方法上同时加入synchronized关键字

场景:

写法如下,刚开始遇到时不懂,后来因为前段处理不当,到后台有几率必定出现多次重复请求,才发现使用了synchronized无效

@Service 
class GameService{
	@Transactional(rollbackFor = Exception.class)
	public synchronized void receiveDuckEgg(BaseUser baseUser) throws Exception {
		//...}
解释:

这种写法会造成在事务未提交前,又执行了一次synchronized方法,而因为事务未提交,所以synchronized方法虽然同步,但是还是会造成脏读。导致处理数据错误的问题。

处理方法:

既然是因为同步synchronized在事务@Transactional之内,而产生的问题。那么我们只要让synchronized的调用层级》事务@Transactional即可,保证事务提交前不能进入同步方法中。可以写一个没有带事务的同步方法,调用另一个service需要执行事务处理的逻辑方法,如:其中a方法为其他service方法(自己测试验证过,暂时不知道专业回答是什么,但是理解上是先进行同步方法直到另一个service层处理完毕[事务处理完毕],才结束阻塞执行下一次方法调用)

@Service 
class aaa{
@Autowired
private GameService gameService;
	public synchronized void a() throws Exception{
		gameService.receiveDuckEgg();
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值