JPA从多进程写入单个数据库 [英] JPA Writing from Multiple Process into Single DB

查看:175
本文介绍了JPA从多进程写入单个数据库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我遇到了一个设计问题:我有几个正在运行的进程正在更新数据库.例如,假设有一个银行系统,我正在记录从一个帐户到另一个帐户的转账.在这种情况下,我必须从源帐户中减去转帐金额,并将同一笔金额作为单个交易记入目标帐户.

So, I've got a design question: I have several processes running that are updating my database. As an example, imagine a banking system, where I'm recording transfers from one account to another. In this case, I have to subtract the transfer amount from the source account and credit the same amount into the destination account as a single transaction.

我想绝对确保在任何情况下都不会破坏我的交易,因此我最初考虑在进行计算并提交更改时对源帐户和目标帐户进行悲观锁定.根据我在网上阅读的有关JPA的内容,似乎不容易支持悲观锁定(至少不是直接支持).

I'd like to make absolutely sure that there are no conditions where my transactions could be corrupted, so I was initially thinking of pessimistic locking of the source and destination accounts while I do the calculations and commit the changes. From what I've read on the web about JPA, it seems like pessimistic locking is not readily supported (at least not directly).

任何人都可以给我一些其他方式的想法,以便我可以确保跨多个流程的交易的完整性吗?

Can anyone give me an idea of other ways that I might be able to ensure the integrity of my transactions across multiple processes?

任何帮助/指针都非常感谢.

Any help/pointers greatly appreciated.

谢谢...

-史蒂夫

推荐答案

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

The preferred method for locking in a system that uses detached persistence (e.g. JPA) is to use optimistic locking as it tends to reduce the amount of contention at the database level, allowing reads to continue while writes are occuring. The way to enable optimistic locking is to add a @Version annotation to a specific version field in your class.

@Entity
public class Account {

    @Id
    private long id;

    @Version
    private long version;

    @Basic
    private BigDecimal balance;
}

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

Then the JPA implementation will manage the version of you object for you. It is recommended that you leave this field private and don't specify getters or setters for it, as you want the JPA implementation to be singly responsible for this field. Your main consideration will then be what action to take when an OptimisticLockException is thrown (which is what happens if someone else has updated one of the accounts before you managed to save your changes.

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

Unfortunately there is no one solution to that problem, the simplest method is to reload the two accounts and retry the transaction, which will work fine if you do not have too many transactions accessing the same account at the same time. In this case you may run into issues where some requests spend the majority of their time retrying the transaction, however it's best to start with the simple solution then change the implementation as your application requires.

这篇关于JPA从多进程写入单个数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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