使用 Ebean ORM 在此处开发 Play Framework 2.3.X 应用程序。
我有一些疑问,我真的想澄清一下定义我的模型时的最佳实践,以使它们变得安全"在并发环境中。
文档中建议的所有模型都扩展了play.db.ebean.Model
,我有一些可以被不同来源修改的实例。
例如,我有这个简单的模型,一个用户
public class User extends Model {
@Id
public Long id;
public String name;
public String surname;
public String email;
public String password;
public int credits
}
在他的帐户上有一些积分。他可以为他们充电,并且可以开始并在背景中有可以消耗他们的工作。 我认为,当同时访问/写入模型时,添加
是明智的选择@Version
public Long version
每个实例的字段,以避免模型中出现不一致的状态,当发生这种情况时,将抛出OptimisticLockException
。
问题是,@Version
注释是否是像我这样的应用程序中的最佳解决方案?
我是否缺少一些我失踪的最佳做法,可以用来减少获得optimisticLockExceptions
的机会,如果是的话,可以使用哪些?
让我们说当系统自动付款时发生optimisticLockExceptions
,例如在信用卡付款后,在交易成功完成时循环是否安全,因此不会抛出optimisticLockExceptions
?
我应该将@Version
注释添加到我的应用程序的每个模型中吗?
很抱歉这么细致,但模型层必须尽可能健壮。 希望你们中的一些人可以帮助我,甚至回答我的一些问题
问候
答案 0 :(得分:1)
乐观锁定的工作原理如下:
UPDATE TABLE_NAME SET fields = :new_fields, version = :old_version + 1 WHERE version = :old_version AND id = :id;
如果没有更新,则意味着自上次读取后对象已更改或删除,因此您需要重复上一次交易。
当您从数据库进行大量读取操作和少量并发写入操作时,乐观锁定是很好的。但是当你在同一个实体上有高并发写入时,你会收到很多optimisticLockExceptions
- >您将执行大量事务回滚。例如,对同一实体的10个并发写操作可以创建多达45个失败的事务,并且只有10个成功。当然,如果你重复交易直到成功。它的潜在漏洞:一些“黑客”可以执行大量请求,在同一个实体上执行并发更新。所以我建议将重复数量限制在合理的数量。
您需要将@Version
添加到需要支持乐观锁定的所有实体。当然,如果某些实体类型仅使用已包含@Version
的另一个实体进行更新,则无法添加它,但是当此行为发生更改时,它可能会在将来产生错误。