【问题标题】:JPA Writing from Multiple Process into Single DBJPA 从多个进程写入单个数据库
【发布时间】:2009-07-10 18:25:26
【问题描述】:

所以,我有一个设计问题:我有几个正在运行的进程正在更新我的数据库。举个例子,想象一个银行系统,我在其中记录从一个账户到另一个账户的转账。在这种情况下,我必须从源账户中减去转账金额,并将相同的金额作为单笔交易记入目标账户。

我想绝对确保不存在我的交易可能被破坏的情况,所以我最初在进行计算并提交更改时考虑对源帐户和目标帐户进行悲观锁定。从我在网上读到的关于 JPA 的内容来看,似乎并不容易支持悲观锁定(至少不是直接支持)。

谁能告诉我其他方法可以确保我的交易在多个流程中的完整性?

非常感谢任何帮助/指针。

谢谢...

--史蒂夫

【问题讨论】:

    标签: java jpa


    【解决方案1】:

    在使用分离持久性(例如 JPA)的系统中锁定的首选方法是使用乐观锁定,因为它倾向于减少数据库级别的争用量,允许在发生写入时继续读取。启用乐观锁定的方法是在类中的特定版本字段中添加@Version 注解。

    @Entity
    public class Account {
    
        @Id
        private long id;
    
        @Version
        private long version;
    
        @Basic
        private BigDecimal balance;
    }
    

    然后 JPA 实现将为您管理对象的版本。建议您将此字段保留为私有,并且不要为其指定 getter 或 setter,因为您希望 JPA 实现单独负责此字段。然后,您的主要考虑因素是当抛出 OptimisticLockException 时要采取什么操作(如果在您设法保存更改之前其他人更新了其中一个帐户,则会发生这种情况。

    不幸的是,这个问题没有一个解决方案,最简单的方法是重新加载两个帐户并重试交易,如果您没有太多交易同时访问同一个帐户,这将正常工作。在这种情况下,您可能会遇到一些请求花费大部分时间重试事务的问题,但是最好从简单的解决方案开始,然后根据应用程序的需要更改实现。

    【讨论】:

    • 是的,我看过乐观锁,但我的印象是客户端代码必须检查版本。如果您说在合并/更新操作时 JPA 提供程序本身将进行此检查(从而避免客户端必须检查的竞争条件),那么这实际上是一种更好的方法。显然我对乐观锁定方法有一个明显的误解......谢谢--Steve
    • 没问题,还要确保在同一个事务中将两个对象合并回持久化上下文中。
    猜你喜欢
    • 2016-02-23
    • 1970-01-01
    • 2015-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-01
    • 1970-01-01
    • 2012-01-31
    相关资源
    最近更新 更多