【问题标题】:binding springjdbc and hibernate session factory in same transaction on same table在同一张表上的同一事务中绑定springjdbc和hibernate会话工厂
【发布时间】:2012-11-09 19:22:53
【问题描述】:

我有一个 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>

【问题讨论】:

  • 可能是因为您使用“createQuery(...)”而不是“update(...)”方法进行插入。
  • 我不知道会影响。但我会试一试。

标签: java spring hibernate transactions sessionfactory


【解决方案1】:

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

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

【讨论】:

  • Hmm.. 有趣的是我应该注意到它,当我运行调用相同的服务作为单元测试的一部分时,它使用相同的事务。同样,我使用相同的弹簧配置。有什么想法吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多