java - HibernateTransactionManager @Transactional(propagation=REQUIRES_NEW) 无法打开 2 个 session

标签 java spring hibernate jpa transactional

有一个批处理作业如下所示:

@Transactional
public void myBatchJob() {
    // retrieves thousands of entries and locks them 
    // to prevent other jobs from touthing this dataset
    entries = getEntriesToProcessWithLock(); 
    additional = doPrepWork(); // interacts with DB
    processor = applicationContext.getBean(getClass());
    while (!entries.isEmpty()) {
        result = doActualProcessing(entries, additional); // takes as many entries as it needs; removes them from collection afterwards
        resultDao.save(result);
    }
}

但是,如果 entries 集合足够大,我偶尔会收到以下错误。

ORA-01000: maximum open cursors exceeded

我决定责怪 doActualProcessing()save() 方法,因为它们最终可能会在一个事务中创建数百个 blob。

明显的出路似乎是将处理分成多个事务:一个用于获取和锁定条目,多个其他事务用于处理和持久化。像这样:

@Transactional
public void myBatchJob() {
    // retrieves thousands of entries and locks them 
    // to prevent other jobs from touthing this dataset
    entries = getEntriesToProcessWithLock(); 
    additional = doPrepWork(); // interacts with DB
    processor = applicationContext.getBean(getClass());
    while (!entries.isEmpty()) {
        processor.doProcess(entries, additional);
    }
}

@Transactional(propagation=REQUIRES_NEW)
public void doProcess(entries, additional) {
    result = doActualProcessing(entries, additional); // takes as many entries as it needs; removes them from collection afterwards
    resultDao.save(result);
}

现在每当调用 doProcess 时我都会得到:

Caused by: org.hibernate.HibernateException: illegally attempted to associate a proxy with two open Sessions

如何让 HibernateTransactionManager 执行 REQUIRES_NEW javadoc 建议的操作:暂停当前事务并启动新事务?

最佳答案

在我看来,问题在于您已经检索了顶部事务中的实体,并且当它们仍然与该事务相关联时,您尝试将它们(代理)传递给将在单独的事务中处理的方法。

我认为你可以尝试两种选择:

1) 在调用之前分离实体 processor.doProcess(entries, extra);:

session.evict(entity); // loop through the list and do this

然后在内部事务中尝试合并:

session.merge(entity);

2) 第二个选项是检索 id,而不是 getEntriesToProcessWithLock 中的实体。然后您将传递不会导致代理问题的普通原始字段。然后,您将检索内部事务内的正确实体。

关于java - HibernateTransactionManager @Transactional(propagation=REQUIRES_NEW) 无法打开 2 个 session ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46363095/

相关文章:

java - 递归聚合键控列表对中的重复项

java - 无法解析导入 javax.servlet.ServletRegistration

java - Spring API 中的返回请求

java - 在不必获取关联的情况下持久化一个新对象

java - 使用 Arquillian Shrinkwrap Resolver Maven 从 pom.xml 读取依赖项

java - 用于在 Java 中保存访问 token 的线程安全类

spring - H2 控制台不适用于 Docker(远程连接 ('webAllowOthers' 被禁用)

java - JPA ManyToMany 持续存在

java - 如何使用 Hibernate 填充 JTable?

java - 尝试使用 twitter4j 更新状态时出现错误 401