我有一个dataSource,我使用Spring3.0.3,Hibernate 3.5.1作为JPA提供者,我使用MyBatis 3.0.2进行一些查询,我的应用程序运行在Tomcat6上。我有一个HibernateDAO和一个MyBatisDAO,当我从同一个方法调用这两个时,用@ transaction注释,看起来它们不共享相同的事务,它们得到不同的连接。
我怎么才能让他们这样做呢?
我试着从DataSourceUtils.getConnection(dataSource)获取连接,但我得到了MyBatis使用的连接,这很奇怪,我以为问题出在MyBatis配置中,它不能使用JpaTransactionManager。即使多次调用DataSoruceUtils.getConnection,也总是会给出相同的连接,这是可以的。
在谷歌搜索之后,我尝试了spring-instrument- tomcat的类加载器(尽管我不知道tomcat是否真的使用它:)
部分applicationContext
<bean class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" id="dataSource">
<property name="driverClassName" value="${database.driverClassName}"/>
<property name="url" value="${database.url}"/>
<property name="username" value="${database.username}"/>
<property name="password" value="${database.password}"/>
</bean>
<bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<tx:annotation-driven mode="aspectj" transaction-manager="transactionManager"/>
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:META-INF/mybatis/mybatis-config.xml" />
</bean>
部分mybatis配置
<settings>
<setting name="cacheEnabled" value="false" />
<setting name="useGeneratedKeys" value="false" />
<setting name="defaultExecutorType" value="REUSE" />
<setting name="lazyLoadingEnabled" value="false"/>
</settings>
部分persistence.xml
<persistence-unit name="persistenceUnit" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
发布于 2011-07-22 01:50:57
我在这里找到了解决方案:What transaction manager should I use for JBDC template When using JPA ?
我使用的是JpaTransactionManager而不是DataSourceTransactionManager。
此事务管理器还支持事务内的直接DataSource访问(即,使用相同DataSource的普通JDBC代码)。这允许混合访问JPA的服务和使用普通JDBC的服务(而不知道JPA)!应用程序代码需要遵循与DataSourceTransactionManager相同的简单连接查找模式(即DataSourceUtils.getConnection(javax.sql.DataSource)或通过TransactionAwareDataSourceProxy)。请注意,这需要配置特定于供应商的JpaDialect。
在我将jpaVendorAdapter添加到我的entityManagerFactory配置中之后,一切都正常了,JdbcTemplate查询和MyBatis都会像预期的那样在同一个事务中运行。根据JavaDoc,我想一个jpaDialect应该足够了,但是现在是凌晨4点。在这里,我现在不会尝试:)
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory">
<property name="persistenceUnitName" value="persistenceUnit"/>
<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="databasePlatform" value="org.hibernate.dialect.PostgreSQLDialect" />
</bean>
</property>
</bean>
发布于 2011-12-05 15:51:44
我没有让MyBatis加入,但正如tewe建议的那样,只需将jpaDialect添加到transactionManager中也可以做到这一点。
<bean class="org.springframework.orm.jpa.JpaTransactionManager"
id="transactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
</property>
</bean>
发布于 2011-07-21 14:20:08
尝试使用:
<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
它直接在JDBC级别上操作。所有的持久化抽象(JPA/iBatis和JdbcTemplate
)最终都使用JDBC,因此您需要在最高公共级别上处理事务。
在您的例子中,您使用的是通过javax.persistence.EntityTransaction
抽象处理事务的JpaTransactionManager
。显然,iBatis不知道JPA事务,因此它可能在事务之外工作。
你不需要任何类加载器/插装魔法,应该可以工作。
https://stackoverflow.com/questions/6777419
复制