在使用spring进行数据库事务管理时,不管是采用JDBC还是hibernate都必须处理好如何获取链接的问题,不能过简单使用getSession(),和 ds.getConnect()来获取数据连接,否则链接一次请求访问就会耗用多个数据连接.
使用HibernateTransactionManager正确的方法是:
xml配置(省略,网上有很多相关的资料)
基础DAO
public class GenericDao {
protected SessionFactory sessionFactory;
//设置sessionFacotry
@Resource(name = "sessionFactory")
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
//获得session
protected Session getSession() {
//使用getCurrentSession(),确保在同一非嵌套型的事务中只消耗一个连接
//如果在此处直接调用getSession()那么在实际操作中,调用该方法多少次,便会消耗多少个连接
return sessionFactory.getCurrentSession();
}
......
}
使用Jdbc Spring事务处理的正确使用方法:
spring Bean 配置文件片段:
org.springframework.jdbc.datasource.DataSourceTransactionManager
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName"
value="com.mysql.jdbc.Driver">
</property>
<property name="url" value="jdbc:mysql://localhost/tech_data"></property>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
</bean>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
基础的数据服务层片段:
public abstract class AbstractServiceBase {
private DataSource ds ;
//此处一定要注意,采用本地线程变量来保存当前线程使用的数据库连接;
//不要直接使用ds.getConnection()去获得connnection;
//否则一个请求会耗用多个连接,在高并发的情况下连接池有可能被耗尽
private static ThreadLocal<Connection> conLocal = new ThreadLocal<Connection>();
//设置数据源,beanName = dataSource
@Resource(name="dataSource")
public void setDataSource(DataSource ds){
this.ds = ds;
}
/**
* 获取一个默认的数据连接
* @return
* @throws SQLException
*/
public Connection getConnection(){
try{
//直接从本地线程中获取,避免重复的调用ds.getConnection();
Connection con = conLocal.get();
if(con != null)
return con;
// 本地线程不存在连接,则直接获取,并把该连接放到本地变量中
con = ds.getConnection();
conLocal.set(con);
return con;
}catch(Exception ex){
ex.printStackTrace();
return null;
}
}
}
为什么会发生这样的事情?,那么这个跟spring的事务处理机制 有关系:
spring事务处理基本原理,主要是通过代理类来完成,以org.springframework.jdbc.datasource.DataSourceTransactionManager.class为例用伪代码进行说明:
1.采用线程本地变量存储要进行事务控制的Connection
class TransactionContext{
private static ThreadLocal(List<Connection>) cons = new ThreadLocal(new ArrayList<Connection>);
//增加一个连接
public void addConnection(conn){
cons.get().add(conn);
}
public void commint(){..}//关闭线程内的所有连接
public void rollBack(){ }回滚所有连接
}
2.生成DataSource的代理类
class DataSourceProxy implements DataSource{
private DataSource target; //被代理的实际的数据源 DataSource
//重写getConnection()方法
//每次调用getConnection()都会把该connection放进ThreadLocal中
Connection getConnection(){
Connect conn = target.getConnection();
TransactionContext.addConnection(conn);
return conn;
}
}
3.对具体的服务类访问使用代理类进行访问
calss ServiceProxy implemens service{
private service target;
private Object handleer(Invocation context){
try{
Method.invoke(target , params[]);
//反射调用具体的类方法,该方法会调用dataSourceProxy.getConnection()
TransactionContext.commit();//统一提交本地线程中的数据库连接
}catch(Exception ex){
TransactionContext.rollback();//统一进行回滚
}
}
}
所以,使用spring 事务管理,必须自己去处理数据连接的唯一性。
原创文章,转载请注明出处,个人原创文章:http://www.chlusoft.com/tech/349.jhtml
相关推荐
Spring 的事务管理是 Spring 框架中一个比较重要的知识点,该知识点本身并不复杂,只是由于其比较灵活,导致初学者很难把握。本教程从基础知识开始,详细分析了 Spring 事务管理的使用方法,为读者理清思路。
此外,Spring事务管理器支持多种类型的事务策略,包括不同的传播行为和隔离级别,允许开发者根据具体业务场景选择最合适的事务管理策略。深入理解Spring声明式事务的工作原理,不仅能帮助开发者更高效地使用Spring...
本书主要介绍了Spring 3.0的核心内容,不仅讲解了Spring 3.0的基础知识,还深入讨论了Spring IoC容器、Spring AOP、使用Spring JDBC访问数据库、集成Hibernate、Spring的事务管理、Spring MVC、单元测试、敏捷开发...
Spring的事务管理及实现,Spring操作Hibernate的事务管理器; 回顾上次课的要点: 代理模式,AOP框架,Spring中AOP的实现方式 一、Spring的事务管理 传统数据库事务的特性: Atomic: 原子性. 事务中的各个...
可以看到配置文件的步骤: 1、 配置数据源 ...4、 Spring中声明事务管理器(根据需要又可分为几种,但都要依赖注入上面的事务管理器,此外还需要配置transationAttributes) 后面的一些普通的bean配置就不用说了
通过学习Spring Boot,我了解了其核心思想和基本原理,以及如何构建RESTful Web服务、使用数据库、进行事务管理等。我学会了使用Spring Boot快速搭建Java Web应用程序,并且能够运用Spring Boot的特性来简化开发流程...
在当今世界上有各种各样的企业级 Java 应用。虽然有些不过是简单的 Web 应用,只使用了 一些本地 JavaBeans 或 POJOs(Plain Old Java Objects),但还有很多是复杂的 N 层...都是由错误或没有使用事务管理策略造成的。
通过学习Spring Boot,我了解了其核心思想和基本原理,以及如何构建RESTful Web服务、使用数据库、进行事务管理等。我学会了使用Spring Boot快速搭建Java Web应用程序,并且能够运用Spring Boot的特性来简化开发流程...
通过学习Spring Boot,我了解了其核心思想和基本原理,以及如何构建RESTful Web服务、使用数据库、进行事务管理等。我学会了使用Spring Boot快速搭建Java Web应用程序,并且能够运用Spring Boot的特性来简化开发流程...
快速入门使用Openshift StatefulSet资源来确保事务管理器的唯一性,并需要PersistentVolume来存储事务日志。 该应用程序支持在StatefulSet资源上缩放。 每个实例将具有自己的“处理中”恢复管理器。 一个特殊的控制...
逍遥大药房管理系统是一个基于Spring Boot框架的Web应用,旨在帮助药房管理人员高效地处理药品库存、销售和顾客服务等相关事务。该系统提供自动化的解决方案,以简化日常操作,提高药房工作效率,同时确保药品信息的...
有些功能很难通过模拟对象进行模拟,相反它们往往只能在真实模块整合后,才能真正运行起来,如事务管理就是其中比较典型的例子。按照Spring的推荐(原话:YoushouldnotnormallyusetheSpringcontainerforunittests:...
通过学习Spring Boot,我了解了其核心思想和基本原理,以及如何构建RESTful Web服务、使用数据库、进行事务管理等。我学会了使用Spring Boot快速搭建Java Web应用程序,并且能够运用Spring Boot的特性来简化开发流程...
其中Hibernate 2相关的封装类位于org.springframework.orm.hibernate2.*包中,而Hibernate 3.0的封装类位于org.springframework.orm.hibernate3.*包中,需要根据您所选用Hibernate版本进行正确选择。 3、Lob字段...
Spring-Batch-POC问题陈述客户现在在用于POS收据管理的端到端解决方案中还存在空白。 客户大概知道大约有10%的pos收据没有正确保存到CMS存储中,并且从DB存储转移到CMS存储时,损失发生在某处。拟议的解决方案DBA...
通过学习Spring Boot,我了解了其核心思想和基本原理,以及如何构建RESTful Web服务、使用数据库、进行事务管理等。我学会了使用Spring Boot快速搭建Java Web应用程序,并且能够运用Spring Boot的特性来简化开发流程...
一、什么是JAVA事务 通常的观念认为,事务仅与数据库相关。 事务必须服从ISO/IEC所制定...持 久性表示已提交的数据在事务执行失败时,数据的状态都应该正确。 通俗的理解,事务是一组原子操作单元,从数据库角度说,就
通过学习Spring Boot,我了解了其核心思想和基本原理,以及如何构建RESTful Web服务、使用数据库、进行事务管理等。我学会了使用Spring Boot快速搭建Java Web应用程序,并且能够运用Spring Boot的特性来简化开发流程...
通过学习Spring Boot,我了解了其核心思想和基本原理,以及如何构建RESTful Web服务、使用数据库、进行事务管理等。我学会了使用Spring Boot快速搭建Java Web应用程序,并且能够运用Spring Boot的特性来简化开发流程...