以下是表结构
公式
余额=原始金额+余额(上一个)
50 = 50 + 0 ID(1)
200 = 150 + 50 ID(2)
关于第二行,我们如何使用hibernate session.save(); 来更新余额我试图写出插入查询但是要知道HQL不支持insert值但是从其他表中选择。
In HQL, only the INSERT INTO … SELECT … is supported; there is no INSERT INTO … VALUES. HQL only support insert from another table.
[source]
如果使用休眠,I first get the balance of max id of customer 1
和then pass the balance to the new object
,那就没关系了!
但在多用户环境中,one user get the balance of max id of customer 1
同时为other user insert the new row and update the balance
。然后获得余额的第一个用户是旧because when first user transaction geting the balance other user insert new row and update balance
。在这种情况下,第一个用户交易相对于他在更新第二个用户交易之前获得的先前余额插入了错误的余额。
是hibernate有公告功能来控制这种情况吗?
我们如何使用具有最新余额的hibernate session.save()来保存事务。 ?
更新我!
答案 0 :(得分:0)
由于表示表行的实体彼此独立,因此hibernate无法知道余额的计算是基于过时的数据。
解决方案1(到目前为止我的首选):计算数据库中的余额(使用触发器)并将余额属性标记为
@Generated(value = GenerationTime.ALWAYS)
以便在写入后更新实体。 Hibernate和数据库将负责其余部分。
如果你必须在应用程序级别进行平衡计算,可以想到多个有一些缺点的解决方案:
解决方案2:不要使用用户事务来提交多用户相关数据。
创建一些内容(例如一些排队机制)来序列化保存请求。在用户独立的事务中进行处理。
缺点:用户将看不到余额,因为它存储在数据库中(但您可能会显示一个瞬态“预测余额”进行当前计算)并且您有一个更复杂的应用程序逻辑和通过序列化的瓶颈
解决方案3:写入(可能)错误数据(或将其留空) - 之后更新
如果要将用于计算的实体的ID存储在新实体中,则可以检查重复项(两个实体具有基于同一实体的余额)并更新该值。
缺点:类似于解决方案2,但没有瓶颈,因为更新可以在后台任务中完成。
解决方案4:重构数据模型以消除实体之间的依赖关系(用于写入)。
您可以使平衡瞬态变化(如果必须显示或使用它,则计算它)。
缺点:仅适用于中等数量的条目,并从数据库中删除此数据,这可能会阻碍您可能要执行的某些查询