2012-11-09 2 views
1

У меня есть метод Spring, который выполняет две операции с базой данных в одной таблице. Один с Hibernate Session Factory, а другой с простой Spring JDBC. Тем не менее, я хочу, чтобы обе были связаны с одной транзакцией. Приведенный ниже код выглядит как две разные транзакции, и первая транзакция блокирует таблицу для второй транзакции.привязка springjdbc и hibernate session factory в той же транзакции в той же таблице

Как убедиться, что обе операции находятся под одной транзакцией. ?

My Service Class

@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> 
+0

Может быть, потому, что вы используете «createQuery (...)» вместо «update (...)» для выполнения вставок. –

+0

Я не знал, что это влияет. Но я попробую. –

ответ

1

TRANSA граница границы определяется соединением, которое используется. Пока вы используете одно и то же соединение (может быть тот же экземпляр сеанса Hibernate, тот же экземпляр менеджера объектов JPA или тот же Spring JdbcTemplate), таблицы, которые заблокированы исключительно в этом соединении, будут недоступны для других, пока транзакция на текущем соединении либо совершается, либо откатывается назад.

В вашем случае, поскольку вы используете разные соединения (через HibernateSession и SimpleJdbcTemplate) для нормального сохранения и массового сохранения, они не могут быть частью одной и той же транзакции. Два действия должны быть последовательно сериализованы один за другим.

+0

Хм .. Забавно, что я должен отметить это, когда я запускаю вызов той же службы, что и часть модульного теста, он использует ту же транзакцию. Опять же, я использую ту же конфигурацию пружины. Есть идеи..? –

+1

Я решил проблему с использованием HibernateTransactionManager –

Смежные вопросы