2014-02-04 4 views
0

Я пытаюсь реализовать Стратегию координации клиентов (ibm-client-orchestration) из-за нашей системной архитектуры. Мы используем слой интеграции, который фактически организует некоторые веб-службы. Вызов веб-служб выполняется в одном блоке работы и делегирует бизнес-уровень, который использует Spring framework. Пример может быть что-то вроде этого:Использование Spring @Transactional распространения в JTA

UserTransaction ut = getUserTransaction() 
ut.begin(); 
// insert data, will be delegated to some jpa repository 
service1.saveData(data) 
// find data inserted above 
service2.findData(data) 
ut.commit(); 

В указанной ссылке, автор предлагает использовать распространение ОБЯЗАТЕЛЬНЫМ на сохранении и распространение ОПОРУ на поиск, который будет пытаться найти данные в журнале транзакций. Почему-то я не знаю, что не могу найти вставленные данные на этапе поиска, учитывая приведенный выше сценарий. Вот некоторая полезная информация, которая может помочь:

  1. мы используем Websphere 8.5. Наша база данных поступает из Websphere, конфигурируется как источник данных XA и берется из JNDI.
  2. Платформа менеджер транзакций с весны сконфигурирован как JtaTransactionManager
  3. Entity Кормушка завод берется из LocalContainerEntityManagerFactoryBean и использует Hibernate JPA Vendor со следующими свойствами:

    jpaProperties.setProperty («hibernate.hbm2ddl.auto» , environment.getRequiredProperty ("entitymanagerfactory.hibernate.hbm2ddl.production")); jpaProperties.setProperty ("hibernate.connection.autocommit", "false"); jpaProperties.setProperty («hibernate.transaction.jta.platform», «org.hibernate.service.jta.platform.internal.WebSphereJtaPlatform»); jpaProperties.setProperty ("hibernate.transaction.manager_lookup_class", "org.hibernate.transaction.WebSphereExtendedJTATransactionLookup");

  4. Я не настроил ни одного поставщика JPA в Websphere, так что это должна быть реализация по умолчанию.

Я упоминал, что если я использую в делегации DAO слоя, метод saveAndFlush() из JPA хранилища, я могу найти, если, но я бы preffer не использовать его и использовать распространение транзакций.

Определение для TransactionManager фасоли:

@Bean 
public PlatformTransactionManager transactionManager() { 
    JtaTransactionManager txManager = new JtaTransactionManager(); 
    txManager.afterPropertiesSet(); 
    return txManager; 
} 
    @Bean 
public EntityManagerFactory entityManagerFactory() { 
    // hibernate vendor 
    HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); 
    vendorAdapter.setDatabase(databaseType()); 
    vendorAdapter.setGenerateDdl(true); 

    // compose entityManager 

    LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean(); 
    factoryBean.setJpaVendorAdapter(vendorAdapter); 
    factoryBean.setDataSource(datasource()); 
    factoryBean.setJtaDataSource(datasource()); 
    // scan packages 
    factoryBean.setPackagesToScan(environment.getRequiredProperty("entitymanager.scan.packages")); 

    // JPA properties 
    factoryBean.setJpaProperties(getEntityManagerFactoryJpaProperties()); 

    factoryBean.afterPropertiesSet(); 

    return factoryBean.getObject(); 
} 

Любые предложения приветствуются. Спасибо.

+0

Вы должны весной управлять жизненным циклом, вы не должны называть 'afterPropertiesSet' самостоятельно, весна сделает это за вас. То же самое с 'getObject()', вы должны просто вернуть «FactoryBean», чтобы весна могла правильно управлять им. –

ответ

0

Для начала вы должны использовать специфический websphre JtaTransactionManager вместо общего. Я хотел бы предложить, используя tag which detects which specific or generic one to use. So basically replace your definition of the JtaTransactionManager` со следующим:

<tx:jta-transaction-manager /> 

Следующая ваш код не использует управления рессоры транзакций, но обычная ССТ сделки либо с помощью аннотаций вести сделки (@Transactional с <tx:annotation-driven /> или использовать впрыскивается PlatformTransactionManager для начать и совершать сделки.

TransactionStatus txStatus = getTransactionManager().getTransaction(null); 
// insert data, will be delegated to some jpa repository 
service1.saveData(data) 
// find data inserted above 
service2.findData(data) 
getTransactionManager().commit(txStatus); 

Также см the reference guide для другого подхода и получения дополнительной информации.

В LocalContainerEntityManagerFactoryBean убедитесь, что вложение объекта jtaDataSource вместо свойства dataSource приведет к дополнительным настройкам.

@Bean 
public FactoryBean<EntityManagerFactory> entityManagerFactory() { 
    LocalContainerEntityManagerFactoryBean lcemfb = new LocalContainerEntityManagerFactoryBean(); 
    lcemfb.setJtaDataSource(dataSource()); 
    // .... Other properties 
    return lcemfb; 
} 

Еще одно замечание о конфигурации спящего режима, то hibernate.connection.* свойства бесполезны из-за введения источника данных, и вы не нуждаетесь в hibernate.transaction.manager_lookup_class, как это (или, по крайней мере, должны) быть уже покрыты сконфигурированной JtaPlatform ,

+0

Я добавил комментарий с тем, как он настраивает transactionManager и entityManagerFactory. Я бы сказал, что это то же самое, что вы упомянули. Я не уверен, есть ли у нас возможность получить оператор транзакций в нашем интеграционном слое, так как этот слой не имеет ничего общего с весной. Спасибо за Ваш ответ. Я попробую, может быть, подход к локатору службы, чтобы получить менеджера транзакций с весны. Если у вас есть другие идеи .. – dumitru

+0

Нет, это не так. Вы используете 'JtaTransactionManager', а не специфичную для websphere. Пространство имен определяет, какую версию использовать. Кроме того, ваш LocalContainerEntityManagerFactoryBean настроен неправильно, вы должны установить свойство 'dataSource' или' jtaDataSource', а не оба. В отношении менеджера транзакций у меня создалось впечатление, что код управлялся Spring, если он не игнорирует эту часть. –

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