1

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

我如何确保两个操作都在一个事务下。?

我的服务等级

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

1 回答 1

1

事务边界由使用的连接控制。只要你使用的是同一个连接(可以是同一个 Hibernate Session 实例,同一个 JPA 实体管理器实例或者同一个 Spring JdbcTemplate),在当前连接上的事务之前,被独占锁定在这个连接中的表将不可供其他人使用要么已提交,要么已回滚。

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

于 2012-11-10T03:26:09.270 回答