事务之间的竞争条件 [英] Race condition between transactions

查看:55
本文介绍了事务之间的竞争条件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Spring MVC 开发 webapp,并且在我的应用程序中有这样的方法:

I am developing webapp using Spring MVC and have a such methods in my application:

@Transactional
public void methodA(Long id, String color) {
    Fruit fruit = entityManager.createNamedQuery("Fruit.findById", Fruit.class).setParameter(1, id).getSingleResult();
    fruit.setColor("color");
    entityManager.merge(fruit);
}

@Transactional
public void methodB(Long id, int price) {
    Fruit fruit = entityManager.createNamedQuery("Fruit.findById", Fruit.class).setParameter(1, id).getSingleResult();
    fruit.setPrice(price);
    entityManager.merge(fruit);
}

这两个方法通常几乎同时被调用,因此会发生竞争条件.有没有办法解决这个问题?我认为将它们放在一个同步方法中并不是一个好主意,因为我预计不同用户同时调用这些方法(数千个),因此可能会导致延迟.如果我错了,请纠正我.

This two methods are often called almost at the same time, and because of that a race condition occurs. Is there a way to fix this problem? I think putting both of them in one synchronized method wouldn't be a good idea, because I expect a lot of calls of these methods (thousands) by different users at the same time, so it can cause delays. Fix me if I am wrong.

推荐答案

处理竞争条件的典型方法是 locks.在 pessimistic 场景中,如果另一个事务当前处于活动状态,您将禁止数据库接受资源上的任何事务.

Typical approaches to deal with race conditions are locks. In a pessimistic scenario you would forbid the database to accept any transactions on a resource if another transaction is currently active.

另一种选择是乐观锁.在将资源写回之前,将其状态与最初读取时的状态进行比较.如果它们不同,则另一个进程更改了该资源,通常以 OptimisticLockException 结束.好消息是,您可以捕获它并立即重试更新该资源.同样,您可以将冲突告诉用户.这是你的选择.

Another option is optimistic locking. Before writing a resource back its state is compared with the one when it was initially read. If they differ, another process has changed that resource, which typically ends up in a OptimisticLockException. The good thing is, you may catch it and retry updating that resource right away. Just the same you could tell the user about the conflict. It's your choice.

这两种解决方案都适用于您的用例.选择哪一个取决于许多因素.我建议你阅读锁并自己选择.

Both solutions would work well for your use case. Which one to pick depends on many factors. I'd propose you read up on locks and choose for yourself.

您可能还需要考虑是否绝对有必要立即将资源提交给数据库.如果您希望它们在下一秒内被更改,您可以将它们存储在内存中并每 n 秒刷新一次,这可以为您节省一些数据库开销.在大多数情况下,这个提议可能是个坏主意.这只是一个想法,没有更深入地了解您的应用程序.

You might also want to consider if is absolutely necessary to commit the resources to the DB right away. If you expect them to be altered in the very next second anyway, you could store them in memory and flush them every n seconds which could save you some DB overhead. In most cases this proposal is probably a bad idea. It's just a thought without having a deeper insight into your application.

这篇关于事务之间的竞争条件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆