Я нашел блог через Google с некоторыми яркими примерами о том, как сделать это:
Осуществляют рефакторинг класс, чтобы быть классом экземпляра и реализовать интерфейс.
Вы уже заявили, что не хотите делать это.
Использование класс экземпляра обертки с делегатами к статическим участникам классов
Выполнение этого можно моделировать статический интерфейс через делегатов.
Использование класс экземпляра обертки с защищенными участниками, которые называют статический класс
, который Это является, вероятно, самым легким дразнить/управлять, не осуществляя рефакторинг, поскольку это может просто быть наследовано от и расширено.
Мне удалось заставить его работать, используя Bitronix вместо JOTM. Bitronix предоставляет LrcXADataSource, который позволяет базе данных, отличной от XA, участвовать в транзакции JTA.
Я думаю, что проблема заключалась в том, что H2 не совместим с XA, а enhydra StandardXADataSource
не делает это волшебным образом (я также закончил использование HSQLDB, но это не имеет отношения к проблеме).
Вот мой контекст Spring, который работает:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config />
<tx:annotation-driven transaction-manager="transactionManager" />
<!-- Bitronix Transaction Manager embedded configuration -->
<bean id="btmConfig" factory-method="getConfiguration"
class="bitronix.tm.TransactionManagerServices">
<property name="serverId" value="spring-btm" />
<property name="journal" value="null" />
</bean>
<!-- create BTM transaction manager -->
<bean id="BitronixTransactionManager" factory-method="getTransactionManager"
class="bitronix.tm.TransactionManagerServices" depends-on="btmConfig,dataSource"
destroy-method="shutdown" />
<bean id="transactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager" ref="BitronixTransactionManager" />
<property name="userTransaction" ref="BitronixTransactionManager" />
<property name="allowCustomIsolationLevels" value="true" />
</bean>
<!-- DataSource definition -->
<bean id="dataSource" class="bitronix.tm.resource.jdbc.PoolingDataSource"
init-method="init" destroy-method="close">
<property name="className" value="bitronix.tm.resource.jdbc.lrc.LrcXADataSource" />
<property name="uniqueName" value="unittestdb" />
<property name="minPoolSize" value="1" />
<property name="maxPoolSize" value="3" />
<property name="allowLocalTransactions" value="true" />
<property name="driverProperties">
<props>
<prop key="driverClassName">org.hsqldb.jdbcDriver</prop>
<prop key="url">jdbc:hsqldb:mem:unittestdb</prop>
<prop key="user">sa</prop>
<prop key="password"></prop>
</props>
</property>
</bean>
<!-- Entity Manager Factory -->
<bean id="emf"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
<property name="generateDdl" value="true" />
<property name="database" value="HSQL" />
</bean>
</property>
<property name="jpaPropertyMap">
<map>
<entry key="hibernate.transaction.manager_lookup_class"
value="org.hibernate.transaction.BTMTransactionManagerLookup" />
<entry key="hibernate.transaction.auto_close_session" value="false" />
<entry key="hibernate.current_session_context_class" value="jta" />
</map>
</property>
</bean>
Когда я пытался интегрировать JOTM и Hibernate, мне в конечном итоге пришлось кодировать свою реализацию ConnectionProvider. Вот как это выглядит прямо сейчас: http://pastebin.com/f78c66e9c
Затем вы указываете свою реализацию в качестве привайдера соединения в свойствах гибернации, и транзакции волшебным образом начинают работать.
Дело в том, что поставщик подключения по умолчанию вызывает getConnection () для источника данных. В вашей собственной реализации вы вызываете getXAConnection (). GetConnection (). В этом разница
Редактировать: (Извините, я, кажется, проснулся только наполовину, когда писал этот абзац. Конечно, вы правы, все должно быть откатано по умолчанию.)
Вы может проверить, что на самом деле делает диспетчер транзакций, например, включив для него вывод отладки.
Предполагая log4j:
log4j.logger.org.springframework.transaction=DEBUG
Диспетчер транзакций дает очень хороший вывод журнала о созданных и объединенных транзакциях, а также о фиксациях и откатах. Это должно помочь вам выяснить, что не работает в вашей настройке.