Spring的事务机制

JAVA EE传统事务机制

通常有两种事务策略:全局事务和局部事务。全局事务可以跨多个事务性资源(即数据源,典型的是数据库和消息队列),通常都需要J2EE应用服务器的管理,其底层需要服务器的JTA支持。而局部事务则与底层采用的持久化技术有关,如果底层直接使用JDBC,需要用Connection对象来操事务。如果采用Hibernate持久化技术,则需要使用session对象来操作事务。

通常的,使用JTA事务,JDBC事务及Hibernate事务的编程流程大致如下,

上图也可以看出,采用传统事务编程,程序代码必须和具体的事务策略的API耦合,如果应用需要切换一种策略,意味着需要大幅修改代码。但是如果使用Spring事务的话,就不会有这个问题了。

Spring事务机制

Sring没有提供任何事务支持,它只是负责包装底层的事务,而在Spring层面,对外提供统一的编程API。Spring事务的核心是PlatformTransactionManager接口,

PlatformTransactionManager代表与具体类型无关的事务接口,可以代表任何事务,包括JDBC事务,Hibernate事务,甚至是JTA事务。

Springa事务机制是一种典型的策略模式,PlatformTransactionManager代表事务管理接口,但它并不知道到底如何管理事务,它只要求事务管理提供开始事务getTransaction(),提交事务commit()和回滚事务rollback()这三个方法,但具体如何实现则交给其实现类完成。编程人员只需要在配置文件中根据具体需要使用的事务类型做配置,Spring底层就自动会使用具体的事务实现类进行事务操作,而对于程序员来说,完全不需要关心底层过程,只需要面向PlatformTransactionManager接口进行编程即可。PlatformTransactionManager接口中提供了如下方法:getTransaction(..), commit(); rollback(); 这些都是与平台无关的事务操作。

getTransaction()的完整写法为 TransactionStatus getTransaction(TransactionDefinition definiton)

这个方法用来返回一个事务对象,其中的参数TransactionDefinition 则可以为事务对象指定各种属性,通常可以指定 事务的隔离属性, 传播属性, 超时,只读 这几个属性。

Spring具体的事务管理需要在配置文件中配置好PlatformTransactionManager,下面是不同类型的事务对应的Spring配置。

  • JDBC数据源的局部事务管理器的配置如下,
 1     <!-- 定义数据源Bean,使用C3P0数据源实现,并注入数据源的必要信息 -->
 2     <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSrouce"
 3         destroy-method="close"
 4         p:driverClass="com.mysql.jdbc.Driver"
 5         p:jdbcUrl="jdbc:mysql://localhost/test"
 6         p:user="root"
 7         p:password=""
 8         p:maxPoolSize="40"
 9         p:minPoolSize="2"
10         p:initialPoolSize="2"
11         p:maxIdleTime="30" />
12     <!-- 配置JDBC数据源的局部数据管理器,使用DataSourceTransactionManager类 -->
13     <bean id="transactionManager"
14         class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
15         p:dataSource-ref="dataSource" />
  • 容器管理的JTA全局事务管理器的配置如下,
1     <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"
2         p:jndiName="jdbc/jpetstore" />
3     <!-- 使用JtaTransactionManager类, 该类实现了PlatformTransactionManager接口 -->
4     <!-- 使用JTA全局事务,Spring容器可以自行从Java EE服务器中获取事务性资源,无需依赖注入 -->
5     <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager" />

对于JTA全局事务,只需要指定事务管理器的实现类JtaTransactionManager即可,Spring容器会自行从J2EE服务器获取数据源,无需显式注入进事务管理器。

  • 基于Hibernate持久化技术的Spring局部事务配置如下,
 1     <!-- 定义数据源Bean,使用C3P0数据源实现,并注入数据源的必要信息 -->
 2     <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSrouce"
 3         destroy-method="close"
 4         p:driverClass="com.mysql.jdbc.Driver"
 5         p:jdbcUrl="jdbc:mysql://localhost/test"
 6         p:user="root"
 7         p:password=""
 8         p:maxPoolSize="40"
 9         p:minPoolSize="2"
10         p:initialPoolSize="2"
11         p:maxIdleTime="30" />
12     <!-- 定义Hibernate的SessionFactory, SessionFactory需要依赖数据源,注入dataSource -->
13     <bean id="sessionFactory"
14         class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"
15         p:dataSource-ref="dataSource">
16         <!-- annotatedClasses用来列出全部持久化类 -->
17         <property name="annotatedClasses">
18             <list>
19                 <!-- 以下用来列出所有PO类 -->
20                 <value>com.entity.User</value>
21             </list>
22         </property>
23         <!-- 定义Hibernate的sessionFactory属性 -->
24         <property name="hibernateProperties">
25             <props>
26                 <!-- 指定Hibernate的连接方言 -->
27                 <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
28                 <!-- 是否根据Hibernate映射表创建数据表 -->
29                 <prop key="hibernate.hbm2ddl.auto">update</prop>
30             </props>
31         </property>
32     </bean>
33     <!-- 配置Hibernate的局部数据管理器,使用HibernateTransactionManager类 -->
34     <!-- 该类是PlatformTransactionManager接口针对Hibernate的特定实现 -->
35     <!-- 配置HibernateTransactionManager需要注入sessionFactory -->
36     <bean id="transactionManager"
37         class="org.springframework.orm.hibernate4.HibernateTransactionManager"
38         p:sessionFactory-ref="sessionFactory" />

Spring事务如果采用Hibernate策略,一般需要配置三点:数据源, sessionFactory, 事务管理器。

  • 如果底层采用Hibernate持久层技术,而事务采用JTA全局事务时,配置如下,
 1     <!-- 配置JTA数据源-->
 2     <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"
 3         p:jndiName="jdbc/jpetstore" />
 4     <!-- 定义Hibernate的SessionFactory, SessionFactory需要依赖数据源,注入dataSource -->
 5     <bean id="sessionFactory"
 6         class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"
 7         p:dataSource-ref="dataSource">
 8         <!-- annotatedClasses用来列出全部持久化类 -->
 9         <property name="annotatedClasses">
10             <list>
11                 <!-- 以下用来列出所有PO类 -->
12                 <value>com.entity.User</value>
13             </list>
14         </property>
15         <!-- 定义Hibernate的sessionFactory属性 -->
16         <property name="hibernateProperties">
17             <props>
18                 <!-- 指定Hibernate的连接方言 -->
19                 <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
20                 <!-- 是否根据Hibernate映射表创建数据表 -->
21                 <prop key="hibernate.hbm2ddl.auto">update</prop>
22             </props>
23         </property>
24     </bean>
25     <!-- 使用JtaTransactionManager类,该类是PlatformTransactionManager接口的实现类 -->
26     <!-- 针对全局事务管理的特定实现 -->
27     <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager" />

这与前面的基于Hibernate的Spring事务比起来,就是将数据源换成了JNDI数据源,  将事务管理器换成了JtaTransactionManager.

对于JTA全局事务,因为需要底层应用服务器的支持,而不同应用服务器所提供的JTA全局事务可能存在细节上的差异,因此实际配置全局事务管理器时可能需要使用JtaTransactionManager的子类,例如Oracle的JavaEE应用服务器提供的OC4JJtaTransactionManager,Oracle为WebLogic提供的WebLogicJtaTransactionManager, IBM为WebSphere提供的WebSphereUowTransactionManager等。

从上面各种事务类型的Spring配置可以看出,当应用程序采用Spring事务管理时,应用程序无需与具体的事务API耦合,应用程序只需要面向PlatormTransactionManager接口编程即可,ApplicationContext会根据配置文件选择合适的事务策略实现类(即PlatormTransactionManager的实现类)。

那么在具体在Spring中如何进行事务控制编程呢,通常有两种方式,

编程式事务管理:就是直接在代码中使用PlatormTransactionManager提供的三个抽象方法进行事务流程控制。也可以在Spring容器中获取PlatormTransactionManager类型的Bean,该Bean总是PlatormTransactionManager的具体实现类的实例,具体的实现类则由ApplicationContext按照策略模式进行选择,编程人员无需关心,只需要面向接口编程即可。

声明式事务管理:这种方式不需要讲事务控制流程写入代码中,而是通过AOP的方式,完全由配置文件完成事务的织入。即XML配置文件可以为业务组件配置事务代理,事务代理为业务组件提供事务控制。现在这种方式是最好的,源码侵入性最低。

当使用声明式事务时,只需要写好配置文件,配置需要事务控制的组件种类,业务组件就会在AOP机制下被织入事务控制,而编程人员不需要写任何事务管理代码,可以专注于业务组件的开发。因此通常都推荐使用声明式事务管理。

使用声明式事务管理

时间: 2024-10-19 00:58:34

Spring的事务机制的相关文章

Spring 事务机制详解

Spring事务机制主要包括声明式事务和编程式事务,此处侧重讲解声明式事务,编程式事务在实际开发中得不到广泛使用,仅供学习参考. Spring声明式事务让我们从复杂的事务处理中得到解脱.使得我们再也无需要去处理获得连接.关闭连接.事务提交和回滚等这些操作.再也无需要我们在与事务相关的方法中处理大量的try…catch…finally代码.我们在使用Spring声明式事务时,有一个非常重要的概念就是事务属性.事务属性通常由事务的传播行为,事务的隔离级别,事务的超时值和事务只读标志组成.我们在进行事

实例详解Spring的事务传播机制(二)

上面我们讨论了NEVER和MANDATORY的作用,下面我们接着讨论其他情况. 3. SUPPORTS 如果有事务则加入该事务,如果没有存在的事务则以非事务的方式运行. 我们先让insertSubTable方法在无事务的情况下运行.配置文件为: <tx:attributes>       <!--     <tx:method name="insertSuperTable" propagation="REQUIRED"/>      -

atitit.spring hibernate的事务机制 spring不能保存对象的解决

atitit.spring hibernate的事务机制 spring不能保存对象的解决 sessionFactory.openSession() 不能. . log黑头马sql语言.. sessionFactory.getCurrentSession().update(user); 中间走ok兰..log黑头也有累.. 在Spring中使用Hibernate.假设我们配置了TransactionManager.那么我们就不应该调用SessionFactory的openSession()来获得S

Spring框架事务管理机制

一.事务的基本原理Spring事务 的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事务功能的.对于纯JDBC操作数据库,想要用到事务,可以按照以下步骤进行:    获取连接 Connection con = DriverManager.getConnection()    开启事务con.setAutoCommit(true/false);    执行CRUD    提交事务/回滚事务 con.commit() / con.rollback();    关闭连接

Spring分布式事务

[如何实现XA式.非XA式Spring分布式事务] [http://www.importnew.com/15812.html] 在JavaWorld大会上,来自SpringSource的David Syer跟大家分享了Spring应用的几种事务处理机制.读完此文,你可以了解可以用分布式事务做些什么.不能做什么以及如何.何时避免使用XA,何时必须使用.

Spring的事务管理

事务 事务:是逻辑上一组操作,要么全都成功,要么全都失败. 事务特性(ACID) 原子性:事务不可分割 一致性:事务执行的前后,数据完整性保持一致 隔离性:一个事务执行的时候,不应该受到其他事务的打扰 持久性:一旦结束,数据就永久的保存到数据库 如果不考虑隔离性 脏读:一个事务读到另一个事务未提交数据 不可重复读:一个事务读到另一个事务已经提交数据(update)导致一个事务多次查询结果不一致 虚读:一个事务读到另一个事务已经提交数据(insert)导致一个事务多次查询结果不一致 事务的隔离级别

Spring中事务管理

1.什么是事务? 事务是逻辑上的一组操作,这组操作要么全部成功,要么全部失败 2.事务具有四大特性ACID 1)原子性(Atomicity):即不可分割性,事务要么全部被执行,要么就全部不被执行.如果事务的所有子事务全部提交成功,则所有的数据库操作被提交,数据库状态发生转换:如果有子事务失败,则其他子事务的数据库操作被回滚,即数据库回到事务执行前的状态,不会发生状态转换. 2)一致性(Consistency):事务的执行使得数据库从一种正确状态转换成另一种正确状态.例如对于银行转账事务,不管事务

spring笔记--事务管理之声明式事务

事务简介: 事务管理是企业级应用开发中必不可少的技术,主要用来确保数据的完整性和一致性, 事务:就是一系列动作,它们被当作一个独立的工作单元,这些动作要么全部完成,要么全部不起作用. Spring中使用事务: 作为一个受欢迎的企业应用框架,Spring在不同的事务管理API上定义了一个抽象层,而开发时不必了解底层的事务管理API,就可以使用Spring的事务管理机制. Spring既支持编程式的事务管理,也支持声明式的事务管理,大多数情况我们选择后者. 编程式事务管理:将事务管理代码嵌入到业务代

Spring高级事务管理难点剖析

1Spring事务传播行为 所谓事务传播行为就是多个事务方法相互调用时,事务如何在这些方法间传播.Spring支持7种事务传播行为 PROPAGATION_REQUIRED(加入已有事务) 如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中.这是最常见也是默认的方式. PROPAGATION_SUPPORTS(跟随环境) 支持当前事务,如果当前没有事务,就以非事务方式执行. PROPAGATION_MANDATORY(需要事务) 使用当前的事务,如果当前没有事务,就抛出异