并行运行多个JPA事务
我有两个(或更多)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向数据库提交多个事务并让数据库处理并发问题?
EntityManager
不适合多个线程使用。 您需要为每个线程获取EntityManager
单独实例。
实际上,如果你使用EJB或Spring,你可以使用事务范围的EntityManager
,它可以在多个线程中使用(它是一个将实际工作委托给独立的线程绑定的EntityManager
实例的代理),但我认为这不是你的情况。
要在跨多个事务处理对象时处理并发问题,可以在对象上获取锁定。 Optimistic
锁定或Pessimistic
锁定可以与适当的锁定模式一起使用。
通过entityManager.lock(entity, LockModeType.READ)
锁定版本化对象将确保它将阻止任何脏读和不可重复读 。
LockModeType.WRITE
将强制增加/更新实体的版本列。