在同一个表上的同一事务中绑定springjdbc和hibernate会话工厂

时间:2012-11-09 19:22:54

标签: java spring hibernate transactions sessionfactory

我有一个Spring服务方法,它在同一个表上执行两个数据库操作。一个使用Hibernate Session Factory,另一个使用普通的Spring JDBC。但是,我希望两者都绑定到一个事务中。使用下面的代码,看起来创建了两个不同的事务,第一个事务将表锁定为第二个事务。

如何确保两个操作都在单个事务中。 ?

我的服务类

@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)

  }
}

弹簧配置

<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>

1 个答案:

答案 0 :(得分:1)

事务边界由使用的连接控制。只要您使用相同的连接(可以是相同的Hibernate Session实例,相同的JPA实体管理器实例或相同的Spring JdbcTemplate),在当前连接上的事务之前,其他人无法使用在此连接中独占锁定的表是承诺还是回滚。

在您的情况下,由于您使用不同的连接(通过HibernateSessionSimpleJdbcTemplate)进行正常保存和批量保存,因此它们不能属于同一事务。这两个动作必须一个接一个地序列化。