`

Spring-JDBC/ORM 统一事务管理解决方案

 
阅读更多

若使用 MyBatis[JDBC] 与hibernate[ORM] 框架结合,且 使用 相同的事务:

 

解决方案三种:

 

1: 将JDBC事务打开,且Hibernate事务关闭,再修改 hibernate sessionFactory的 useTransactionAwareDataSource  属性为true

 

<!-- 事务管理器配置, 使用jdbc事务 -->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource" />
	</bean>
<!-- 使用annotation定义事务 -->
	<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
<!-- Hibernate配置 -->
	<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<property name="namingStrategy">
			<bean class="org.hibernate.cfg.ImprovedNamingStrategy" />
		</property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">${hibernate.dialect}</prop>
				<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
				<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
				<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
				<prop key="hibernate.cache.provider_configuration_file_resource_path">ehcache/ehcache-hibernate-local.xml</prop>
			</props>
		</property>
		<property name="packagesToScan" value="org.springtest.entity" />
		<property name="useTransactionAwareDataSource" value="true"/>
	</bean>

 参加Spring源码:

 

SessionFactory org.springframework.orm.hibernate3.LocalSessionFactoryBean.buildSessionFactory() throws Exception
if (dataSource != null) {
				Class providerClass = LocalDataSourceConnectionProvider.class;
				if (isUseTransactionAwareDataSource() || dataSource instanceof TransactionAwareDataSourceProxy) {
					providerClass = TransactionAwareDataSourceConnectionProvider.class;
				}
				else if (config.getProperty(Environment.TRANSACTION_MANAGER_STRATEGY) != null) {
					providerClass = LocalJtaDataSourceConnectionProvider.class;
				}
				// Set Spring-provided DataSource as Hibernate ConnectionProvider.
				config.setProperty(Environment.CONNECTION_PROVIDER, providerClass.getName());
			}
 第二种: 使用JTA事务:
<beans>

  <bean id="myDataSource1" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName value="java:comp/env/jdbc/myds1"/>
  </bean>

  <bean id="myDataSource2" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="java:comp/env/jdbc/myds2"/>
  </bean>

  <bean id="mySessionFactory1" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="dataSource" ref="myDataSource1"/>
    <property name="mappingResources">
      <list>
        <value>product.hbm.xml</value>
      </list>
    </property>
    <property name="hibernateProperties">
      <value>
        hibernate.dialect=org.hibernate.dialect.MySQLDialect
        hibernate.show_sql=true
      </value>
    </property>
  </bean>

  <bean id="mySessionFactory2" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="dataSource" ref="myDataSource2"/>
    <property name="mappingResources">
      <list>
        <value>inventory.hbm.xml</value>
      </list>
    </property>
    <property name="hibernateProperties">
      <value>
        hibernate.dialect=org.hibernate.dialect.OracleDialect
      </value>
    </property>
  </bean>

  <bean id="myTxManager" class="org.springframework.transaction.jta.JtaTransactionManager"/>

  <bean id="myProductDao" class="product.ProductDaoImpl">
    <property name="sessionFactory" ref="mySessionFactory1"/>
  </bean>

  <bean id="myInventoryDao" class="product.InventoryDaoImpl">
    <property name="sessionFactory" ref="mySessionFactory2"/>
  </bean>

  <!-- this shows the Spring 1.x style of declarative transaction configuration -->
  <!-- it is totally supported, 100% legal in Spring 2.x, but see also above for the sleeker, Spring 2.0 style -->
  <bean id="myProductService"
      class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    <property name="transactionManager" ref="myTxManager"/>
    <property name="target">
      <bean class="product.ProductServiceImpl">
        <property name="productDao" ref="myProductDao"/>
        <property name="inventoryDao" ref="myInventoryDao"/>
      </bean>
    </property>
    <property name="transactionAttributes">
      <props>
        <prop key="increasePrice*">PROPAGATION_REQUIRED</prop>
        <prop key="someOtherBusinessMethod">PROPAGATION_REQUIRES_NEW</prop>
        <prop key="*">PROPAGATION_SUPPORTS,readOnly</prop>
      </props>
    </property>
  </bean>

</beans>

 

第三种:使用被代理的数据源:

 

使用 TransactionAwareDataSourceProxy

如果不得已要显式获取数据连接,除了使用 DataSourceUtils 获取事务上下文绑定的连接外,还可以通过 TransactionAwareDataSourceProxy 对数据源进行代理。数据源对象被代理后就具有了事务上下文感知的能力,通过代理数据源的 getConnection() 方法获取的连接和使用 DataSourceUtils.getConnection() 获取连接的效果是一样的。

下面是使用 TransactionAwareDataSourceProxy 对数据源进行代理的配置:


清单 11.applicationContext.xml:对数据源进行代理

				
<bean id="dataSource"
    class="org.apache.commons.dbcp.BasicDataSource"
    destroy-method="close"
    p:driverClassName="oracle.jdbc.driver.OracleDriver"
    p:url="jdbc:oracle:thin:@localhost:1521:orcl"
    p:username="test"
    p:password="test"
    p:defaultAutoCommit="false"/>
    
<!-- ①对数据源进行代理-->
<bean id="dataSourceProxy" 
    class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy"
    p:targetDataSource-ref="dataSource"/>
    
<!-- ②直接使用数据源的代理对象-->
<bean id="jdbcTemplate"
    class="org.springframework.jdbc.core.JdbcTemplate"
    p:dataSource-ref="dataSourceProxy"/>
    
<!-- ③直接使用数据源的代理对象-->
<bean id="jdbcManager"
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
    p:dataSource-ref="dataSourceProxy"/>

 

对数据源进行代理后,我们就可以通过数据源代理对象的 getConnection() 获取事务上下文中绑定的数据连接了。

因此,如果数据源已经进行了 TransactionAwareDataSourceProxy 的代理,而且方法存在事务上下文,那么清单 1 的代码也不会生产连接泄漏的问题。

 

参加 void org.mybatis.spring.SqlSessionFactoryBean.setDataSource(DataSource dataSource)

public void setDataSource(DataSource dataSource) {
		if (dataSource instanceof TransactionAwareDataSourceProxy) {
			this.dataSource = ((TransactionAwareDataSourceProxy) dataSource)
					.getTargetDataSource();
		} else
			this.dataSource = dataSource;
	}

 以及:void org.springframework.jdbc.datasource.DataSourceTransactionManager.setDataSource(DataSource dataSource)

public void setDataSource(DataSource dataSource)
    {
        if(dataSource instanceof TransactionAwareDataSourceProxy)
            this.dataSource = ((TransactionAwareDataSourceProxy)dataSource).getTargetDataSource();
        else
            this.dataSource = dataSource;
    }

 

及: void org.springframework.orm.jpa.JpaTransactionManager.setDataSource(DataSource dataSource)

 

对于 Hibernate 的 sessionFactory 取得的所有的实际数据库连接皆取自于 

Connection org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourcedataSource) throws SQLException

 

而就是这个方法保证了取得的数据库连接 是 绑定到当前线程的真正数据库连接.

 

对于MyBatis官方文档中就是 使用 JDBC事务管理器便能够管理事务,则

 

只要 数据库被代理了,且使用的是 JDBC事务管理器则能够保证事务的一致性,

 

 

 另参见Hibernate配置:void org.springframework.orm.hibernate3.AbstractSessionFactoryBean.setUseTransactionAwareDataSource(boolean useTransactionAwareDataSource)

和 http://www.blogjava.net/i369/articles/194855.html

但JPA事务管理器取得的数据库连接也是 DataSourceUtils.doGetConnection 取得的连接

分享到:
评论

相关推荐

    spring对jdbc的支持jar包

    在实际使用中,Spring JDBC通常与Spring的其他模块结合,如Spring ORM(Object-Relational Mapping)和Spring AOP(Aspect-Oriented Programming),以提供更完整的数据访问解决方案。例如,Hibernate或MyBatis可以...

    最新 spring-framework-4.2.5 英文官方文档,包含html、pdf、epub等

    综上所述,Spring Framework 4.2.5 是一套强大的企业级应用开发工具,涵盖了多个核心领域,提供了一站式的解决方案,使得开发者能够更高效、更灵活地构建复杂的Java应用。通过阅读官方文档(html、pdf、epub格式),...

    spring-framework-4.3.24.RELEASE-dist.zip

    6. **Spring Security**:Spring的安全模块提供了一套完整的安全解决方案,包括身份验证、授权、CSRF防护等,为Web应用提供了强大的安全保障。 7. **Test Support**:Spring的测试框架支持单元测试和集成测试,提供...

    spring-framework-3.1.2.RELEASE jar包

    Spring框架是Java开发中不可或缺的一部分,它为构建企业级应用提供了全面的解决方案。Spring 3.1.2.RELEASE是该框架的一个重要版本,虽然它已经相对较老,但仍然在某些项目中被广泛使用,尤其是那些无法立即升级到...

    官方原版源码spring-framework-5.0.10.RELEASE.zip

    6. **Spring Batch**:这是一个处理大量数据的批处理框架,提供了一套完整的解决方案,包括读写操作、事务管理、错误处理等。 7. **Spring Security**:是Spring生态中的安全框架,提供认证、授权等功能,保护Web...

    spring-framework-4.2.4.RELEASE-dist Spring资源包

    Spring框架是Java开发中最广泛应用的轻量级框架之一,它为构建高质量的、可维护的、松耦合的Java应用程序提供了全面的解决方案。这个资源包"spring-framework-4.2.4.RELEASE-dist"是Spring框架的一个特定版本,4.2.4...

    spring-framework-5.0.2.RELEASE官方完整包加官方文档

    总的来说,Spring Framework 5.0.2.RELEASE是一个强大的工具,它提供了全面的解决方案,涵盖了从Web应用开发到后台服务的各个层面。配合官方文档,开发者可以深入理解并充分利用Spring的各种特性,提升开发效率和...

    spring分别与jdbc和hibernate结合的事务控制--案例

    在IT行业中,Spring框架以其强大的依赖...无论是在简单还是复杂的业务逻辑中,Spring都能提供可靠的事务管理方案,确保数据的正确性和一致性。通过理解并熟练运用这些知识点,开发者可以构建出更加健壮和易维护的系统。

    docs4dev_Spring Framework 中文文档_5.1.3.RELEASE.zip

    9. **Spring Batch**:对于批量处理和批处理任务,Spring Batch 提供了一套完整的解决方案,包括事务管理、错误处理和重试机制。 10. **消息驱动**:Spring 提供了对JMS(Java消息服务)的支持,允许应用进行异步...

    spring-mybatis整合jar包,spring-mybatis整合jar包

    Spring Mybatis是一个流行的...通过以上库文件的整合,Spring Mybatis能提供一套完整的解决方案,帮助开发者快速、高效地构建数据访问层,同时利用Spring的其他功能如事务管理、AOP等,提高代码的可维护性和灵活性。

    spring-4.1.7 jar包

    总结来说,Spring 4.1.7 jar包是Java Web开发的重要工具,它提供了一整套解决方案,涵盖了从对象管理、数据访问到Web服务和测试等多个层面,极大地简化了开发流程并提高了代码质量。开发者可以通过深入学习Spring的...

    spring-framework-5.3.20

    - **RESTful API**:Spring MVC提供了一套完整的解决方案,用于构建RESTful风格的Web服务。 - **数据库操作**:Spring Data支持多种持久层技术,简化了数据库操作。 - **分布式事务**:Spring的事务管理功能,确保跨...

    spring4.3.9相关jar包文件

    8. **安全**:Spring Security是Spring的一个子项目,提供了一套全面的安全解决方案,包括身份验证、授权、会话管理等。虽然不是核心jar包,但通常与Spring框架一起使用。 9. **WebSocket支持**:Spring 4.3.9版本...

    最新版完整包 spring-5.3.9.RELEASE-dist.zip

    11. **Spring Batch**:对于批量处理和工作流任务,Spring Batch 提供了一个全面的解决方案,包括事务管理、错误处理和重试机制。 12. **Spring Integration**:Spring Integration 提供了连接不同系统和协议的能力...

    mybatis-spring-1.3.3.jar官方下载

    Spring 框架则是一个开源的应用框架,它提供了一个全面的企业级应用开发解决方案,包括事务管理、数据访问、AOP(面向切面编程)、MVC(模型-视图-控制器)等。Spring 以其 IoC(Inversion of Control,控制反转)和...

    spring-framework-4.3.5 所有JAR文件包

    - Spring Batch是基于JSR 352标准的批处理框架,提供了一套完整的批处理解决方案。 10. **Spring Security**: - 它是一个全面的安全管理框架,提供身份验证、授权和访问控制等功能,保护Web应用程序免受安全威胁...

    spring-5.3.9-dist.zip

    此外,Spring Cloud与Spring Boot结合,提供了微服务开发的全套解决方案,包括服务发现、配置管理、熔断机制等。 总的来说,Spring Framework 5.3.9是一个强大且成熟的开发框架,它提供的各种组件和工具极大地提高...

    官方源码 spring-framework-5.3.4.zip

    此外,Spring Security模块提供了全面的安全解决方案,包括认证、授权等,确保应用程序的安全性。 通过对Spring Framework 5.3.4源码的深入学习,开发者不仅可以提升自己的技术能力,还能了解到更多设计原则和最佳...

Global site tag (gtag.js) - Google Analytics