如何在Spring Batch Writer中使用Hibernate无状态会话

时间:2013-07-03 19:07:12

标签: java hibernate batch-processing spring-batch

有没有办法在spring-batch Writer中使用StatelessSession,它正在参与当前的spring-batch JDBC-Transaction和Hibernate-Transaction?

我试过

public class MyWriter implements ItemWriter<SomeClass> {
    @Override
    public void write(final List<? extends SomeClass> items) throws Exception {
        StatelessSession session = sessionFactory.openStatelessSession();
        Transaction tx = session.beginTransaction();
        for(SomeCLass item : items){
            session.insert(item);
        }
        tx.commit();
        session.close();
    }
}

但实际上它是在spring-batch处理的会话之外创建一个新的HibernateSession。如何将StatelessSession附加到当前状态 - Session

背景:我很乐意使用无状态会话,因为方法myStatefullHibernateSession.save(item)正在加载也不属于会话的关联对象。我这样做是为了最小化创建的sql数量,在我的批处理环境中,这节省了大量的cpu成本,并且在处理数百万条数据记录时减少了运行时间。

休眠:3.6.10
Spring-Batch:2.2.0

编辑:在axtavt的帮助下,我让它使用相同的JDBC-Transaction,但我还使用了hibernate属性hibernate.jdbc.batch_size,这会导致以下内容观察:

  1. 如果在创建的beginTransaction上使用commitStatelessSession,那么spring-batch的事务控制将不再起作用(作者的后续异常将不会回滚)
  2. 如果没有在StatelessSession上创建一个hibernate-transaction,则spring-batch的事务控制将起作用,但spring-batch-commit不会提交{{{}中的insert / update / delete-statements。 1 {}} Hibernate在BatchingBatcher
  3. 总结一下:我只需要一个StatelessSession而不是标准的hibernate有状态 - StatelessSession

1 个答案:

答案 0 :(得分:0)

如果Spring Batch使用常规的Spring事务管理(HibernateTransactionManager等),那么您可以尝试使用Connection获取绑定到当前事务的DataSourceUtils,并在打开时使用它StatelessSession 1}}:

Connection c = DataSourceUtils.getConnection(dataSource);
StatelessSession session = sessionFactory.openStatelessSession(c);

您可能需要HibernateTransactionManager了解用于创建DataSource的{​​{1}},请参阅HibernateTransactionManager.setDataSource()