1

同じテーブルで2つのデータベース操作を実行するSpringサービスメソッドがあります。1つはHibernateSessionFactoryを使用し、もう1つはプレーンなSpringJDBCを使用します。ただし、両方を1つのトランザクションにバインドする必要があります。以下のコードでは、2つの異なるトランザクションが作成され、最初のトランザクションが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 セッション インスタンス、同じ JPA エンティティ マネージャー インスタンス、または同じ Spring JdbcTemplate の可能性があります) を使用している限り、この接続で排他的にロックされているテーブルは、現在の接続でトランザクションが実行されるまで、他のユーザーが使用することはできません。コミットまたはロールバックされます。

あなたの場合、通常の保存と一括保存に ( と を介しHibernateSessionSimpleJdbcTemplate) 異なる接続を使用しているため、それらを同じトランザクションの一部にすることはできません。2 つのアクションは、順番にシリアル化する必要があります。

于 2012-11-10T03:26:09.270 に答える