并行运行多个 JPA 事务

发布于 2024-11-06 21:26:55 字数 689 浏览 0 评论 0原文

我有两个(或更多)Java 线程使用 JPA 从 mysql 数据库创建、更新和删除实体。为了实现这一目标,我有一个 PersistenceLayer 类,它创建 EntityManager 并为所有实体提供保存、更新和删除方法,如下所示:

public void saveEntity(Entity entity) {
    manager.getTransaction().begin();
    manager.persist(entity);
    manager.getTransaction().commit();
}

public void saveEntity2(Entity2 entity) {
    manager.getTransaction().begin();
    manager.persist(entity);
    manager.getTransaction().commit();
}

如果一个线程同时进入 saveEntity 操作,另一个线程同时进入 saveEntity2 操作,则两个线程都会尝试从EntityManager 将会失败。然而,我一直认为底层数据库能够管理多个事务,特别是当两个事务都在不同的行甚至不同的表上工作时。当然,我可以同步这些块,但这意味着一次只能有一个数据库连接,这将无法扩展到创建多个线程的多个用户。

我在这里做了什么错误的假设?是否可以通过JPA向数据库提交多个事务并让DB处理并发问题?

I have two (or more) Java Threads creating, updating and deleting entities from a mysql database using JPA. To achieve this I have a PersistenceLayer class creating the EntityManager and providing save, update and delete methods for all my entities looking like:

public void saveEntity(Entity entity) {
    manager.getTransaction().begin();
    manager.persist(entity);
    manager.getTransaction().commit();
}

public void saveEntity2(Entity2 entity) {
    manager.getTransaction().begin();
    manager.persist(entity);
    manager.getTransaction().commit();
}

If one thread enters operation saveEntity and the other saveEntity2 at the same time, both will try to get the transaction from the EntityManager wich will fail. However I always thought that the underlying database is able to manage multiple transactions, especially if both are working on different rows or even different tables. Of course I could synchronize the blocks, but that would mean only one DB connection is possible at a time which will not scale to multiple users creating several threads.

What wrong assumption am I doing here? Is it possible to submit multiple transactions to a database via JPA and let the DB handle concurrency issues?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

柳絮泡泡 2024-11-13 21:26:55

EntityManager 不适合由多个线程使用。您需要为每个线程获取单独的 EntityManager 实例。

实际上,如果您使用 EJB 或 Spring,您可以使用事务范围的 EntityManager,它可以在多个线程中使用(它是一个代理,它将实际工作委托给单独的线程绑定实例 EntityManager ),但我认为这不是你的情况。

EntityManager is not intended to be used by multiple threads. You need to obtain separate instances of EntityManager for each thread.

Actually, if you use EJB or Spring you can use a transaction-scoped EntityManager, which can be used from multiple threads (it's a proxy which delegates actual work to separate thread-bound instances of EntityManager), but I think it's not your case.

桃扇骨 2024-11-13 21:26:55

为了处理跨多个事务处理对象时的并发问题,可以在对象上获取锁。 乐观悲观锁定都可以与适当的锁定模式一起使用。

通过 entityManager.lock(entity, LockModeType.READ) 锁定版本化对象将确保防止任何脏读不可重复读取

LockModeType.WRITE 将强制增加/更新实体的版本列。

To handle concurrency issues when the object is being processed accross multiple transactions, lock can be acquired on the object. Either Optimistic or Pessimistic locking can be used with appropriate lock-modes.

Locking the versioned object by entityManager.lock(entity, LockModeType.READ) will ensure that it will prevent any Dirty Read & Non-Repeatable Read.

LockModeType.WRITE will force incrementing/updating the version column of the entity.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文