2012-11-09 38 views
1

我有一個在同一個表上執行兩個數據庫操作的Spring服務方法。一個使用Hibernate Session Factory,另一個使用普通的Spring JDBC。但是,我希望兩者都被綁定到單個事務中。使用下面的代碼,它看起來像創建了2個不同的事務,並且第一個事務鎖定了第二個事務的表。在同一個表上的同一事務中綁定springjdbc和hibernate會話工廠

如何確保兩項操作均屬於單項交易。 ?

我的服務類

@Service 
public class MyService{ 

@Autowired 
IMyDao mydao; 

@Transactional 
public void myMethod(){ 
...  
mydao.save(entity); //This uses hibernate 
... 
mydao.saveBulk(List<Entity> entities>; //This uses spring jdbc for performance reasons. 
} 

... 
} 

MyDAOImpl.class

public class MyDAOImpl extends SimpleJDBCSupport implements IMyDao{ 
    private SessionFactory sessionFactory; 

@Autowired 
public MyDAOImpl (
     @Qualifier("sessionFactory") final SessionFactory sessionFactory, 
     @Qualifier("dataSource") final DataSource dataSource) { 
    this.sessionFactory = sessionFactory; 
    this.setDataSource(dataSource); 
} 
    public void save(Entity entity){ 
     sessionFactory.getCurrentSession().createQuery("insert into tableA... ").executeUpdate() ; 


    } 
    public void saveBulk(List<Entity> entites){ 
     ...// prepare batch insert data. 
     this.getJdbcTemplate().batchUpdate("insert into tableA... " , batchPreparedStmtSetter) 

    } 
} 

Spring配置文件

<bean id="dataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean"> 
    <property name="xaDataSourceClassName" value="${advdb.jdbc.dataSourceClassName}" /> 
    <property name="xaProperties" ref="dataSourceProperties" /> 
    <property name="uniqueResourceName" value="${advdb.jdbc.uniqueResourceName}" /> 
    <property name="testQuery" value="${advdb.jdbc.testQuery}" /> 
    <property name="minPoolSize" value="${advdb.jdbc.minPoolSize}" /> 
    <property name="maxPoolSize" value="${advdb.jdbc.maxPoolSize}" /> 
    <property name="maxIdleTime" value="${advdb.jdbc.maxIdleTime}" /> 
    <property name="borrowConnectionTimeout"  value="${advdb.jdbc.borrowConnectionTimeout}" /> 
    <property name="reapTimeout" value="${advdb.jdbc.reapTimeout}" /> 
    <property name="maintenanceInterval" value="${advdb.jdbc.maintenanceInterval}" /> 
</bean> 

<!-- Session Factory --> 

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean" p:dataSource- ref="dataSource"> 
    <property name="hibernateProperties"> 
     <props> 
      <prop key="hibernate.dialect">${hibernate.dialect}</prop> 
      <prop key="hibernate.show_sql">${hibernate.show_sql}</prop> 
      ... 
          ... 
</bean> 
+0

可能是因爲您正在使用「createQuery(...)」而不是「update(...)」方法來執行插入操作。 –

+0

我不知道這影響。但我會試一試。 –

回答

1

的transa設備邊界由所使用的連接管理。只要您使用相同的連接(可以是相同的Hibernate Session實例,相同的JPA實體管理器實例或相同的Spring JdbcTemplate),在此連接中獨佔鎖定的表將不可用於其他人,直到當前連接上的事務被提交或回滾。

對於您的情況,由於正在使用不同的連接(通過HibernateSessionSimpleJdbcTemplate)進行常規保存和批量保存,因此它們不能屬於同一事務。這兩項行動必須一個接一個地序列化。

+0

嗯..有趣的是,我應該注意到,當我運行調用相同的服務作爲單元測試的一部分時,它使用相同的事務。再次,我使用相同的彈簧配置。有任何想法嗎..? –

+1

我解決了使用HibernateTransactionManager的問題 –

相關問題