Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Hibernate 从异步方法重复调用em.merge会锁定数据库表_Hibernate_Jpa_Transactions - Fatal编程技术网

Hibernate 从异步方法重复调用em.merge会锁定数据库表

Hibernate 从异步方法重复调用em.merge会锁定数据库表,hibernate,jpa,transactions,Hibernate,Jpa,Transactions,我正在使用JBoss/Wildfly 7.1中的Java持久性API与MSSQL数据库进行接口。我有一个长期运行的异步函数,它定期插入和更新表,但每次更新之间有几秒钟的时间。当这个函数运行时,表在事务中被锁定,我无法从Java应用程序内部或外部查询表。下面是我如何实现DAO的示例: @Stateless class Dao { @PersistenceContext(unitName = "persistenceUnit") private EntityManager em;

我正在使用JBoss/Wildfly 7.1中的Java持久性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不主动修改表时,我能做些什么来防止它锁定表?

除了MySQL(使用可重复读取)之外,大多数关系数据库系统的默认隔离级别都是读取提交的。所有数据库都允许您设置默认事务隔离级别

您可以尝试使用READ_UNCOMMITTED来绕过长期运行的更新问题。使用Hibernate,意味着设置:

<property name="hibernate.connection.isolation">1</property>
1
除了MySQL(它使用可重复读取),大多数关系数据库系统的默认隔离级别都是读取提交的。所有数据库都允许您设置默认事务隔离级别

您可以尝试使用READ_UNCOMMITTED来绕过长期运行的更新问题。使用Hibernate,意味着设置:

<property name="hibernate.connection.isolation">1</property>
1

由于服务被注入到一个总体EJB中,因此从getEntity调用开始,事务似乎一直处于打开状态。放置@TransactionaAttribute(TransactionaAttribute.REQUIRES\u NEW)时,另一个事务从未关闭,因此合并无法打开新事务。通过在调用getEntity方法时将@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)放在getEntity方法上,事务中将不会考虑该连接。这样,当调用merge方法时,容器就可以自由地为合并打开一个新事务。

由于服务被注入到一个总体EJB中,因此从getEntity调用开始,事务似乎一直处于打开状态。放置@TransactionaAttribute(TransactionaAttribute.REQUIRES\u NEW)时,另一个事务从未关闭,因此合并无法打开新事务。通过在调用getEntity方法时将@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)放在getEntity方法上,事务中将不会考虑该连接。这样,当调用合并方法时,容器就可以自由地为合并打开一个新事务。

获取线程转储以找出“卡住”的内容和确切位置,并打开SQL日志记录,以便查看执行的内容可能导致锁定。获取线程转储以找出“卡住”的内容和确切位置,并打开SQL日志记录,以便您可以查看执行的哪些操作可能导致锁定。