繁体   English   中英

春季-在cron作业中具有多个事务的Hibernate会话管理?

spring - Hibernate session management with multiple transactions in a cron job?

提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供   中文繁体   英文版本   中英对照 版本,有任何建议请联系yoyou2525@163.com。

在春季/冬眠的应用程序中,我每天晚上都会运行一些cronjobs。 其中之一应在以下多个事务中完成其工作:

@Scheduled(cron = "...")
public void cron ( ) 
{
    batchJob();
}

@Transactional(propagation = Propagation.NEVER)
public void batchJob ( )
{
    List<Customer> customers = getCustomers();
    for (Customer customer : customers
    {
        doSomething(customer);
    }
}

@Transactional(readOnly = true)
protected List<Customer> getCustomers ( )
{
    return customerRepository.getCustomers();
}

@Transactional
protected void doSomething (Customer customer )
{
         // LazyInitializationException 
         customer.getAddress();
         // ...
}

我的弹簧配置的一部分:

<!-- Transaction -->
<tx:annotation-driven mode="aspectj" />

<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>

这里的关键是我不想有一个长期运行的事务。 所以首先我得到所有客户,并为每个客户调用一种事务方法。 (我希望发布的代码足以理解问题)

当然,我会收到LazyInitializationException,因为提交“ getCustomer”周围的事务时,Spring将关闭会话。

我能想到的可能解决方案:

  • 我可以使用OpenSessionInViewInterceptor,但这是一个Web组件

  • 我可以使用session.merge(customer)重新附加分离的对象

  • 这是Propagation.Nestedtransaction的案例吗? 嵌套事务的语义是什么? 大多数数据库没有嵌套事务(postgresql有,但我从未使用过,这称为两阶段提交)

  • 我可以重写该方法以使用customerId并在第二个事务中再次加载客户

现在我有两个关于我的问题的问题:

  1. 您如何编写测试来重现上述错误?

  2. 我如何轻松地围绕此进行公开会议,或者在多个事务中完成一堆工作的最佳方法是什么?

1 个回复

据我了解,您仅需要在非事务性测试中调用cron() ,就我不太了解您对测试的第一个问题。

关于可能的解决方案,我认为最好的方法是在初始查询中加载ID(只要您获得每个Customer的新实例进行处理都没有关系)。

请注意,带有merge()解决方案比具有id的解决方案没有优势,它只会增加内存使用量和网络带宽消耗。 而且据我记得, JpaTransactionManager不支持嵌套事务。

从理论上讲,在这种情况下,您可以使用扩展的持久性上下文而不是事务性的上下文,但是我认为不可能以这种方式配置Spring Data JPA。

编辑:如果您不喜欢它的外观,则可以封装低级详细​​信息以将您的业务逻辑与它们分离,如下所示:

interface CustomerProcessor {
    public void process(Customer c);
}

public void processCustomersInBatchJob(CustomerProcessor processor) {
    List<Long> ids = ...;
    for (Long id: ids) {
        processCustomer(id, processor);
    }
}

@Transactional
protected void processCustomer(Long id, CustomerProcessor processor) {
    Customer c = getCustomer(id);
    processor.process(c);
}
1 多个事务的Hibernate会话管理?

为多个数据库事务维护Hibernate会话的最佳方法是什么? 我是否需要每次打开和关闭每个会话,还是应该依靠getCurrentSession() ? 最好的方法是什么? ...

4 Spring + Hibernate会话管理

我一直在阅读有关使用Spring和Hibernate的内容,我对会话管理感到困惑。 希望有人能为我清除一些事情, 首先,我不知道在使用HibernateTemplate时如何管理会话。 当您在模板上调用方法Eg Save()时会打开和关闭会话吗? 当您使用find()方法时,是否返回 ...

6 Spring Hibernate 默认会话管理

所以我有一个 3 层应用程序。 通过 spring boot starter jpa 配置休眠自动。 和使用@EnableJpaRepositories(enttityManagerFactory, transactionManager, basepackages) 的配置类 我的问题是,如果控制器 ...

7 在单个休眠会话中创建多个事务

我创建了一个Quartz Job,它在JBoss服务器的后台运行,负责定期更新一些统计数据(加上一些数据库标志) 加载并坚持我正在使用Hibernate 4.一切正常,除了一个hick up。 整个线程,即Job被包装在单个事务中,在一段时间内(随着数据量的增加)变得巨大并且担心一些 ...

8 如何将spring与hibernate会话和事务管理集成?

我是hibernate和spring的初学者。 我已经了解了hibernate事务划分(至少我认为是这样)。 但在编写了一些像这样的方法之后: 我开始想要避免它,并希望在我的方法之外自动完成它,这样我只会写“//在这做一些事情”部分。 我已经阅读了有关TransactionProx ...

9 Spring Boot和Hibernate 5-EntityManagerFactory会话管理

我正在使用Spring-boot和Hibernate开发第一个Web应用程序。 我已经这样写了我的第一个DAO: 像这样在每个方法中调用entityManagerFactory是否正确? 我已经阅读了一些有关此的文章,我了解到该会话在每个查询结束时都被该工具关闭了,对吗? ...

10 Spring + Hibernate:@Transactional方法中的会话管理

关于这个主题有很多问题,但我仍然不清楚在事务中管理会话的过程。 我们假设有一些回购: 这段代码是否正确? 每次操作运行时,我是否真的需要手动打开和关闭(以及刷新和清除)会话? 我可以使用getCurrentSession()而忘记刷新和关闭(因为我猜交易可能会照顾我的生命周期) ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2021 STACKOOM.COM