我正在使用JBoss / Wildfly 7.1中的Java Persistence API与MSSQL数据库进行交互。我有一个长期运行的异步函数,定期插入和更新到表中,但每次更新之间有几秒钟。当此函数运行时,表在事务中被锁定,我无法从Java应用程序内部或外部查询表。下面是我如何实现DAO的示例:
@Stateless
class Dao {
@PersistenceContext(unitName = "persistenceUnit")
private EntityManager em;
public void mergeEntity(Entity e){
em.merge(e);
}
public Entity getEntity(int id){
return em.find(Entity.class,id);
}
}
class Service {
@Inject
private Dao dao;
private void updateEntity(int id){
Entity e = dao.getEntity(id)
//do update logic
dao.mergeEntity(e);
}
}
我也尝试过请求mergeEntity
方法的新交易:
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void mergeEntity(Entity e){
em.merge(e);
}
当我这样做时,合并永远不会执行,操作就会挂起。打开Hibernate的跟踪日志记录并未发现任何表明存在问题的内容。有什么办法可以防止Hibernate在没有主动修改它的情况下锁定它吗?
答案 0 :(得分:0)
除MySQL(使用REPEATABLE_READ)外,大多数关系数据库系统的默认隔离级别为READ_COMMITTED。所有数据库都允许您设置默认事务隔离级别。
您可以尝试使用READ_UNCOMMITTED来绕过长时间运行的更新问题。使用Hibernate,意味着设置:
<property name="hibernate.connection.isolation">1</property>
答案 1 :(得分:0)
看起来事务从getEntity调用开始保持打开状态,因为服务被注入到一个总体EJB中。放置@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)时,其他事务从未关闭,因此合并永远不会打开新事务。通过在getEntity方法上调用@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)时,在事务中不会考虑连接。这样,当调用merge方法时,容器可以自由地为合并打开一个新事务。