2013-07-03 76 views
1

有沒有辦法在彈簧批處理Writer中使用StatelessSession,它正在參與當前的Spring-batch JDBC-Transaction和Hibernate-Transaction?如何在SpringBatch Writer中使用Hibernate StatelessSession

我試圖

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(); 
    } 
} 

,但實際上它是從外面通過彈簧批量處理的會話創建一個新的HibernateSession。如何將StatelessSession附加到當前狀態完全-Session

背景:我很樂意使用無狀態會話,因爲方法myStatefullHibernateSession.save(item)正在加載不屬於會話的關聯對象。我這樣做是爲了儘量減少創建的sqls數量,並且在我的批處理環境中,這樣可以節省大量的cpu成本,並且在處理數百萬條數據記錄時減少運行時間。

休眠:3.6.10
彈簧批次:2.2.0

編輯:隨着axtavt的幫助下,我得到它的工作使用相同的JDBC的事務,但我使用除休眠屬性hibernate.jdbc.batch_size這導致以下觀察:

  1. 如果使用所創建的StatelessSession彈簧批次的事務控制不工作的任何更多beginTransactioncommit(稍後excepti作者不會回滾)
  2. 如果沒有在StatelessSession上創建一個hibernate事務,spring-batch的事務控制將會起作用,但是spring-batch-commit不會提交說謊的insert/update/delete-語句Hibernate的BatchingBatcherStatelessSession

總結一下:我只需要一個StatelessSession而不是我的作家中的標準休眠狀態-。

回答

0

如果Spring Batch的使用普通的Spring事務管理(HibernateTransactionManager等),那麼你可以嘗試獲得Connection綁定到使用DataSourceUtils,並用它當前的事務打開StatelessSession時:

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

您可能需要使HibernateTransactionManager知道您用於創建SessionFactoryDataSource,請參閱HibernateTransactionManager.setDataSource()

+0

一個好主意,但遺憾的是不能正常工作在我的情況。這會創建一個綁定到當前連接和sql事務的StatelessSession。在我的情況下,我使用的hibernate屬性'hibernate.jdbc.batch_size'設置爲> 50。這導致當完成writer方法時,所有當前位於statelesssession-jdbc-batch中的insert/update/delete-statement都沒有被提交,因爲sql-transaction正在被調用,而不是無狀態的session等待提交jdbc-batch-package。 (我會調整我的問題) – thomas

相關問題