若使用 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源码:
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通常与Spring的其他模块结合,如Spring ORM(Object-Relational Mapping)和Spring AOP(Aspect-Oriented Programming),以提供更完整的数据访问解决方案。例如,Hibernate或MyBatis可以...
综上所述,Spring Framework 4.2.5 是一套强大的企业级应用开发工具,涵盖了多个核心领域,提供了一站式的解决方案,使得开发者能够更高效、更灵活地构建复杂的Java应用。通过阅读官方文档(html、pdf、epub格式),...
6. **Spring Security**:Spring的安全模块提供了一套完整的安全解决方案,包括身份验证、授权、CSRF防护等,为Web应用提供了强大的安全保障。 7. **Test Support**:Spring的测试框架支持单元测试和集成测试,提供...
Spring框架是Java开发中不可或缺的一部分,它为构建企业级应用提供了全面的解决方案。Spring 3.1.2.RELEASE是该框架的一个重要版本,虽然它已经相对较老,但仍然在某些项目中被广泛使用,尤其是那些无法立即升级到...
6. **Spring Batch**:这是一个处理大量数据的批处理框架,提供了一套完整的解决方案,包括读写操作、事务管理、错误处理等。 7. **Spring Security**:是Spring生态中的安全框架,提供认证、授权等功能,保护Web...
Spring框架是Java开发中最广泛应用的轻量级框架之一,它为构建高质量的、可维护的、松耦合的Java应用程序提供了全面的解决方案。这个资源包"spring-framework-4.2.4.RELEASE-dist"是Spring框架的一个特定版本,4.2.4...
总的来说,Spring Framework 5.0.2.RELEASE是一个强大的工具,它提供了全面的解决方案,涵盖了从Web应用开发到后台服务的各个层面。配合官方文档,开发者可以深入理解并充分利用Spring的各种特性,提升开发效率和...
在IT行业中,Spring框架以其强大的依赖...无论是在简单还是复杂的业务逻辑中,Spring都能提供可靠的事务管理方案,确保数据的正确性和一致性。通过理解并熟练运用这些知识点,开发者可以构建出更加健壮和易维护的系统。
9. **Spring Batch**:对于批量处理和批处理任务,Spring Batch 提供了一套完整的解决方案,包括事务管理、错误处理和重试机制。 10. **消息驱动**:Spring 提供了对JMS(Java消息服务)的支持,允许应用进行异步...
Spring Mybatis是一个流行的...通过以上库文件的整合,Spring Mybatis能提供一套完整的解决方案,帮助开发者快速、高效地构建数据访问层,同时利用Spring的其他功能如事务管理、AOP等,提高代码的可维护性和灵活性。
总结来说,Spring 4.1.7 jar包是Java Web开发的重要工具,它提供了一整套解决方案,涵盖了从对象管理、数据访问到Web服务和测试等多个层面,极大地简化了开发流程并提高了代码质量。开发者可以通过深入学习Spring的...
- **RESTful API**:Spring MVC提供了一套完整的解决方案,用于构建RESTful风格的Web服务。 - **数据库操作**:Spring Data支持多种持久层技术,简化了数据库操作。 - **分布式事务**:Spring的事务管理功能,确保跨...
8. **安全**:Spring Security是Spring的一个子项目,提供了一套全面的安全解决方案,包括身份验证、授权、会话管理等。虽然不是核心jar包,但通常与Spring框架一起使用。 9. **WebSocket支持**:Spring 4.3.9版本...
11. **Spring Batch**:对于批量处理和工作流任务,Spring Batch 提供了一个全面的解决方案,包括事务管理、错误处理和重试机制。 12. **Spring Integration**:Spring Integration 提供了连接不同系统和协议的能力...
Spring 框架则是一个开源的应用框架,它提供了一个全面的企业级应用开发解决方案,包括事务管理、数据访问、AOP(面向切面编程)、MVC(模型-视图-控制器)等。Spring 以其 IoC(Inversion of Control,控制反转)和...
- Spring Batch是基于JSR 352标准的批处理框架,提供了一套完整的批处理解决方案。 10. **Spring Security**: - 它是一个全面的安全管理框架,提供身份验证、授权和访问控制等功能,保护Web应用程序免受安全威胁...
此外,Spring Cloud与Spring Boot结合,提供了微服务开发的全套解决方案,包括服务发现、配置管理、熔断机制等。 总的来说,Spring Framework 5.3.9是一个强大且成熟的开发框架,它提供的各种组件和工具极大地提高...
此外,Spring Security模块提供了全面的安全解决方案,包括认证、授权等,确保应用程序的安全性。 通过对Spring Framework 5.3.4源码的深入学习,开发者不仅可以提升自己的技术能力,还能了解到更多设计原则和最佳...