为了账号安全,请及时绑定邮箱和手机立即绑定

关于@Transcation sychonized方法的可重复读机制 ,会不会出现多次修改记录?

关于@Transcation sychonized方法的可重复读机制 ,会不会出现多次修改记录?

蛊毒传说 2022-10-03 14:09:57
有个问题,一个spring容器管理项目(service是单例),一个方法会被并发访问,方法为同步方法且用@Transcation注解,数据库隔离机制为可重复读,业务是这样的,用户交易后本地会产生一条交易流水记录,status为0, 然后调用第三方支付,第三方支付会同步异步回调本地这个方法两次, 这个方法内部先判断status是不是为0 ,然后账户增加10元, 那假如同步异步同时回调,那会不会出现该用户账户增加两次金额情况@Transcationpublic synchronized void callback() {查询交易流水记录 statusif(status == 0) {用户帐号 增加10元交易流水记录 status 设为1} else {不作为}}
查看完整描述

3 回答

?
慕神8447489

TA贡献1780条经验 获得超1个赞

在单个JVM的情况下,是没有问题的,但是在集群的环境下有问题,因为Sychronized关键字实际上是JVM级别的,多个JVM不起作用。
建议题主采用的方式:
  1)采用悲观锁的方式,select的同时做LOCK(select XXXX for update),效率较低;
  2)直接update 加上status=0作为条件:
      int num= update ${yourTable} set status=1 where ${yourCondition} and status = 0;
      if(num == 0 ) {//update失败处理};
推荐采用第二种方式。

查看完整回答
反对 回复 2022-10-06
?
繁星coding

TA贡献1797条经验 获得超4个赞

你这个方法是synchronized,就算是并发,一个进程访问完这个方法,别的进程才能够继续访问。在第一次访问的时候把status设置成1,后面的访问就不会进
if(status == 0) {
用户帐号 增加10元
交易流水记录 status 设为1
}这个判断了,所以不会重复增加。

查看完整回答
反对 回复 2022-10-06
?
偶然的你

TA贡献1841条经验 获得超3个赞

不会,因为不管是先同步还是先异步,操作后status都会置为1,下次回调就会不作为

查看完整回答
反对 回复 2022-10-06
  • 3 回答
  • 0 关注
  • 142 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信