ssm(springmvc+spring+mybatis) 解决并发问题

问题描述:
在项目中遇到一个问题就是用户在更新状态table1时,同时需要记录到其他表(table2)中来保存本次操作。
然后在实际过程中,因为是多线程运行的导致并发问题,即多个用户同时更新一个id的操作,会报table2的唯一性约束。

解决思路(先查询后更新):
遇到这个情况首先想到的是在更新/插入之前先查询数据库的数据,看是否符合更新条件。
举个例子:我的用户表用户原状态为失效00,要更新为生效01,那么我在更新之前先查询一下状态是否为00,如果为00才能更新。
问题:实测发现由于是并发导致每个用户查询来的数据都是失效00,而且会向table2插入多次数据,在向table2插入本次改变数据的时候则报了唯一性冲突。table1也会更新多次。

解决思路(乐观锁):
然后我想到了用乐观锁来解决这个问题,乐观锁其实原理和上面一样,虽然能解决table1只更新一次的问题,但仍然会导致多次插入table2报的唯一性约束。

解决思路(悲观锁):
既然乐观锁不行,那我干脆把表中的这个数据锁住是否能解决呢。实测(假设2个用户同时操作)发现,数据库执行的过程为:
打开事务,查询锁住数据,查询锁住数据,插入数据,插入数据,更新数据。同样会报唯一性约束的问题。
原因是我锁住了table1表,可是查询还是会查出多次且数据一样,均为失效00,只是更新时会排队,同时这种方式容易造成锁表(用户多,查询出来的数据多的情况下)。

解决思路(java synchronized 同步锁:
既然mysql解决不了这个问题,或者解决起来比较麻烦,那我能不能用java的方式解决呢。
这么一想就是为了解决多线程问题,我保证这个方法同一时间只能有一个在运行即可,那肯定使用java 的synchronized 方法就可以实现了。经过实测,的确可行,至此,问题解决。
代码如下:
public synchronized int updateAuditReceive(AuditBean auditBean) throws Exception{
// TODO Auto-generated method stub
}
需要注意的是synchronized 标识需要是用在service层的impl实现类中。同时该方法需要功能单一(即此处只为更新这一个状态)为防止影响其他用户操作。比如我锁了一个方法功能是更新用户信息的,那所有人更新用户信息都需要等待一个一个来,这种并发性要求不高的其实没有必要。只需要把并发性高的那个功能,比如更新用户的id(唯一索引之类的,表中肯定只允许一个存在的)单读拿出来使用同步就可以了。
注意,此种方法有个弊端,就是同一时间只能有一个人更新,就算在操作不同的用户都必须要等待,仅限用于抢红包之类的程序。

PS:如果有不同看法或者我的逻辑有问题的请及时联系我。。虽然我的方法解决了但由于不是很熟悉,不清楚会不会造成其他问题。

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值