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