当前位置: 首页 > 面试题库 >

如何配置Spring使JPA(Hibernate)和JDBC(JdbcTemplate或MyBatis)共享同一事务

仉梓
2023-03-14
问题内容

我只有一个数据源,我使用Spring 3.0.3,Hibernate 3.5.1作为JPA提供程序,并且使用MyBatis 3.0.2进行某些查询,并且我的应用程序在Tomcat 6上运行。当我同时调用HibernateDAO和MyBatisDAO时,从@Transactional注释的同一方法中,它们似乎不共享同一事务,它们获得了不同的连接。
我该怎么做?

我尝试从DataSourceUtils.getConnection(dataSource)获取连接,但得到了MyBatis使用的连接,这很奇怪,我认为问题出在MyBatis配置中,无法使用JpaTransactionManager。即使多次调用DataSoruceUtils.getConnection也会始终提供相同的连接,这没关系。

经过一些谷歌搜索后,我尝试了spring-instrument-tomcat的类加载器(尽管我不知道tomcat是否真的使用它:))

partial 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>

partial mybatis config

<settings>
    <setting name="cacheEnabled" value="false" />
    <setting name="useGeneratedKeys" value="false" />
    <setting name="defaultExecutorType" value="REUSE" />
    <setting name="lazyLoadingEnabled" value="false"/>
</settings>

partial persistence.xml

<persistence-unit name="persistenceUnit" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>

问题答案:

我使用的是JpaTransactionManager,而不是DataSourceTransactionManager。
JavaDoc http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/orm/jpa/JpaTransactionManager.html

This transaction manager also supports direct DataSource access within a transaction (i.e. plain JDBC code working with the same DataSource). This allows for mixing services which access JPA and services which use plain JDBC (without being aware of JPA)! Application code needs to stick to the same simple Connection lookup pattern as with DataSourceTransactionManager (i.e. DataSourceUtils.getConnection(javax.sql.DataSource) or going through a TransactionAwareDataSourceProxy). Note that this requires a vendor-specific JpaDialect to be configured.

在我将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>


 类似资料:
  • 问题内容: 我只有一个数据源,我使用Spring 3.0.3,Hibernate 3.5.1作为JPA提供程序,并使用MyBatis 3.0.2进行一些查询,并且我的应用程序在Tomcat 6上运行。当我同时调用HibernateDAO和MyBatisDAO时,从@Transactional注释的相同方法来看,它们似乎不共享同一事务,它们获得了不同的连接。 我该怎么做? 我尝试从DataSourc

  • 最近,我注意到Spring Data JDBC,所以我决定在一个新的Spring Boot(2.3.1)应用程序中使用它。在我的用例中,我有一个包含两类表的DB模式: 用于存储应用程序(更复杂的)业务逻辑所使用的实体的表。我使用Spring Data JPA(带有底层Hibernate)来处理它们。 表,用于存储彼此之间没有太多关系的简单数据记录(例如来自外部系统的数据记录)。我决定对它们使用Sp

  • 我对Spring Boot是新手,但我对Spring有经验。 我有一个工作启动Spring启动项目。现在我想将它连接到Postgres DB,并能够使用常规查询。具体来说,我们经常在Spring(DAO)中编写以下类型的代码: 问:有人能告诉我在Spring Boot中做同样事情的标准方法是什么吗?要做到这一点,我需要在不同的文件中添加什么(比如所有依赖项和注释等等)。 我知道对你来说,把所有的代

  • 问题内容: 我正在尝试从使用用户名和密码登录到我的MySQL数据库服务器的未加密JDBC连接转移到使用SSL和基于证书的身份验证的连接。我在Spring MVC中使用Hibernate。我的WebAppConfig文件如下所示: 而我的属性配置文件(application.properties)如下: 我已经在/ etc / mysql / certs内部生成了正确的证书,并编辑了my.cnf以指

  • 我正在使用带有spring jdbc事务支持的spring jdbc。 这是我的配置。 使用这个配置,事务对我来说不起作用。我不确定原因,但我能理解的是- 如您所见,jdbcTemplate()和txManager(),这两个方法都调用getDataSource()方法,该方法inturn创建JDBCDataSource。我认为在这两个方法中,我都创建了两个jdbc数据源,因此jdbcTempla

  • 我们使用spring security的JdbcTokenStore来持久化oAuth2访问令牌。同样的应用程序也严重依赖spring数据jpa。两者共享到MySQL数据库的连接池。 Jdbc默认为自动提交模式,而JdbcTokenStore似乎是在自动提交启用的假设下编写的。它从未明确提交更改。 另一方面,Spring-data和JPA需要一个事务来进行写入操作。应用程序使用@Transacti