java - 在同一个表的同一事务中绑定(bind) springjdbc 和 hibernate session 工厂

标签 java spring hibernate transactions sessionfactory

我有一个 Spring 服务方法,可以在同一个表上执行两个数据库操作。一个使用 Hibernate Session Factory,另一个使用普通的 Spring JDBC。但是,我希望将两者绑定(bind)到一个事务中。使用下面的代码,看起来创建了 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)

  }
}

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>

最佳答案

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

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

关于java - 在同一个表的同一事务中绑定(bind) springjdbc 和 hibernate session 工厂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13314562/

相关文章:

java - IntelliJ 中的变量命名代码样式

java - 如何强制 Eclipse Applet Viewer 执行安全检查?

java - TreeModel 中的内部类的属性不可读

java - 如何在 Spring Rest @PathVariable 中正确转义 '/'

java - 榛子 : changing configuration programatically doesnt work

java - java中的继承 : object state and behavior

java - 如何在运行时(在 IDE 中)从类路径引用配置文件

java - Spring MVC Rest 客户端获取 HttpClientErrorException : 404 null

java - Hibernate单向一对一

java - 如何在 Hibernate 不生成任何表的情况下使用 Hibernate Envers (@Audited)