`
wanjianfei
  • 浏览: 319296 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

spring 事务管理

阅读更多

关键字: 事务 spring

Spring框架引人注目的重要因素之一是它全面的事务支持。Spring框架提供了一致的事务管理抽象,这带来了以下好处:
为复杂的事务API提供了一致的编程模型,如JTA、JDBC、Hibernate、JPA和JDO
支持 声明式事务管理
提供比大多数复杂的事务API(诸如JTA)更简单的,更易于使用的 编程式 事务管理API
非常好地整合Spring的各种数据访问抽象


传统上,J2EE开发者有两个事务管理的选择: 全局 或 本地 事务。
全局事务由应用服务器管理,使用JTA。
局部事务是和资源相关的,比如一个和JDBC连接关联的事务。这个选择有深刻的含义。
例如,全局事务可以用于多个事务性的资源(典型例子是关系数据库和消息队列)。
使用局部事务,应用服务器不需要参与事务管理,并且不能帮助确保跨越多个资源(需要指出的是多数应用使用单一事务性的资源)的事务的正确性。

全局事务有一个重大的缺陷,代码需要使用JTA:一个笨重的API(部分是因为它的异常模型)。此外,JTA的UserTransaction通常需要从JNDI获得,这意味着我们为了JTA,需要 同时 使用JNDI 和 JTA。
使用全局事务的首选方式是通过EJB的 CMT(容器管理事务):CMT是 声明式事务管理 的一种形式(区别于 编程式事务管理)。
重大的缺陷是CMT绑定在JTA和应用服务器环境上,并且只有我们选择使用EJB实现业务逻辑,或者至少处于一个事务化EJB的外观(Facade)后才能使用它。

本地事务. 本地事务容易使用,但也有明显的缺点:它们不能用于多个事务性资源。
例如,使用JDBC连接事务管理的代码不能用于全局的JTA事务中。
另一个缺点是局部事务趋向于入侵式的编程模型。
Spring解决了这些问题。它使应用开发者能够使用在 任何环境 下使用 一致 的编程模型.Spring框架同时提供声明式和编程式事务管理。声明事务管理是多数使用者的首选,在多数情况下是被推荐使用的。
如何解决??AOP?回调
使用编程式事务管理,开发者直接使用Spring框架事务抽象,这个抽象可以使用在任何底层事务基础之上。
使用首选的声明式模型,开发者通常书写很少的或没有与事务相关的代码,因此不依赖Spring框架或任何其他事务API。

Spring事务抽象的关键是事务策略的概念。这个概念由org.springframework.transaction.PlatformTransactionManager接口定义。
TransactionStatus 对象可能代表一个新的或已经存在的事务(如果在当前调用堆栈有一个符合条件的事务。如同J2EE事务环境,一个 TransactionStatus 也是和执行 线程 绑定的)。
TransactionDefinition接口指定:
1、事务隔离:当前事务和其它事务的隔离的程度。例如,这个事务能否看到其他事务未提交的写数据?
2、事务传播:通常在一个事务中执行的所有代码都会在这个事务中运行。但是,如果一个事务上下文已经存在,有几个选项可以指定一个事务性方法的执行行为:例如,简单地在现有的事务中继续运行(大多数情况);或者挂起现有事务,创建一个新的事务。Spring提供EJB CMT中常见的事务传播选项。
3、事务超时: 事务在超时前能运行多久(自动被底层的事务基础设施回滚)。
4、只读状态: 只读事务不修改任何数据。只读事务在某些情况下(例如当使用Hibernate时),是一种非常有用的优化。
这些设置反映了标准概念。

事务的四个特性:原子、一致、隔离、持久。

TransactionStatus 接口为处理事务的代码提供一个简单的控制事务执行和查询事务状态的方法。

使用Spring时,无论你选择编程式还是声明式的事务管理,定义一个正确的 PlatformTransactionManager 实现都是至关重要的。
按照Spring的良好风格,这种重要定义都是通过IoC实现的。

一般来说,选择PlatformTransactionManager实现时需要知道当前的工作环境,如JDBC、JTA、Hibernate等。

局部事务:我们需要定义一个Hibernate的 LocalSessionFactoryBean,应用程序从中获取到Hibernate Session 实例。

如果是一个JEE容器提供的 DataSource,它将由JEE容器自身,而不是Spring框架来管理事务。????
这种情况中'txManager' bean的类型为 HibernateTransactionManager。同样地,DataSourceTransactionManager 需要一个指向 DataSource 的引用,而 HibernateTransactionManager 需要一个指向 SessionFactory 的引用。
JEE容器提供的 DataSource????全局事务确认。全局事务,可以支持任何事务性资源。

现在应该比较清楚的是:不同的事务管理器是如何创建的,以及它们如何被连接到相应的需要被同步到事务的资源上。
剩下的问题是:直接或间接地使用一种持久化API(JDBC、Hibernate、JDO等)的应用代码,如何确保通过相关的 PlatformTransactionManager 来恰当地获取并操作资源,来满足事务同步,这些操作包括:创建、复用、清理 和 触发(可能没有)。
高层次方案:
首选的方法是使用Spring的高层持久化集成API。对所有持久化API都采用这种 模板 方法,包括 JdbcTemplate、HibernateTemplate和JdoTemplate类.
低层次方案
在较低层次上,有以下这些类:DataSourceUtils(针对JDBC),SessionFactoryUtils(针对Hibernate),PersistenceManagerFactoryUtils(针对JDO)等等。
当对应用代码来说,直接同原始持久化API特有的资源类型打交道是更好的选择时,这些类确保应用代码获取到正确的Spring框架所管理的bean,事务被正确同步,处理过程中的异常被映射到一致的API。
保证了跨数据库——甚至其他持久化技术——的移植性。
这些类同样可以在没有Spring事务管理的环境中工作良好(事务同步能力是可选的),所以无论你是否使用Spring的事务管理,你都可以使用这些类。

DataAccessExceptions好处?

声明式事务管理:
最符合 非侵入式 轻量级容器的理念。
Spring的声明式事务管理是通过Spring AOP实现的。
因为事务方面的代码与Spring绑定并以一种样板式风格使用, 不过尽管如此,你一般并不需要理解AOP概念就可以有效地使用Spirng的声明式事务管理。

EJB CMT和Spring声明式事务管理的相似以及不同之处出发是很有益的。重要

回滚规则的概念比较重要:它使我们能够指定什么样的异常(和throwable)将导致自动回滚。
我们在配置文件中声明式地指定,无须在Java代码中。
我们仍旧可以通过调用 TransactionStatus 的 setRollbackOnly() 方法编程式地回滚当前事务。

默认式Spring处理声明式事务管理的规则遵守EJB习惯(只在遇到unchecked exceptions时自动回滚),但通常定制这条规则会更有用。

Spring的事务管理是通过AOP代理实现的。
其中的事务通知由元数据(目前基于XML或注解)驱动。
代理对象与事务元数据结合产生了一个AOP代理,它使用一个PlatformTransactionManager 实现品配合TransactionInterceptor,在方法调用前后实施事务。

推荐做法是在Spring框架的事务架构里指出当context的事务里的代码抛出 Exception 时事务进行回滚。
Spring框架的事务基础架构代码将从调用的堆栈里捕获到任何未处理的 Exception,并将标识事务将回滚。

注意Spring框架的事务基础架构代码将默认地 只 在抛出运行时和unchecked exceptions时才标识事务回滚。
也就是说,当抛出一个 RuntimeException 或其子类例的实例时才会回滚。从事务方法中抛出的Checked exceptions将 不 被标识进行事务回滚。

第一种方法可以配置哪些 Exception类型将被标识进行事务回滚。 no-rollback-for rollback-for
第二种方法是通过 编程式 方式来指定回滚事务。


假设你有许多服务对象,你想为他们分别设置 完全不同 的事务语义。
在Spring中,你可以通过分别定义特定的 <aop:advisor/> 元素, 让每个advisor采用不同的 'pointcut' 和 'advice-ref' 属性,来达到目的。

两个拥有完全不同的事务配置的bean。

默认的 <tx:advice/> 设置如下:
事务传播设置 是 REQUIRED
隔离级别是DEFAULT
事务是 读/写
事务超时默认是依赖于事务系统的,或者事务超时没有被支持。
任何 RuntimeException 将触发事务回滚,但是任何 checked Exception 将不触发事务回滚

除了基于XML文件的声明式事务配置外,你也可以采用基于注解式的事务配置方法。Java 5(Tiger)。

一般配置都有个默认的问题:如果你用 'transactionManager' 来定义 PlatformTransactionManager bean的名字的话,你就可以忽略 <tx:annotation-driven/> 标签里的 'transaction-manager' 属性。 如果 PlatformTransactionManager bean你要通过其它名称来注入的话,你必须用 'transaction-manager' 属性来指定它。

请注意只是使用 @Transactional 注解并不会启用事务行为, 它仅仅 是一种元数据,能够被可以识别 @Transactional 注解和上述的配置适当的具有事务行为的beans所使用。
<tx:annotation-driven/>元素的出现 开启 了事务行为。

Spring团队的建议是你只在具体的类上使用 @Transactional 注解, 而不要注解在接口上。
你当然可以在接口(或接口方法)上使用 @Transactional 注解, 但是这只有在你使用基于接口的代理时它才会生效。
因为注解是 不能继承 的, 这就意味着如果你正在使用基于类的代理时,事务的设置将不能被基于类的代理所识别,而且对象也不会被事务代理所包装 (这是很糟糕的)。

‘自我调用’是不会触发事务的,比如说,一个在目标对象中调用目标对象其他方法的方法是不会触发一个事务的,即使这个方法被标记为 @Transactional!

在多数情形下,方法的事务设置将被优先执行。

在由Spring管理的事务中,请记住 物理 和 逻辑 事务存在的差异, 以及传播设置是如何影响到这些差异的。

获得到一个拥有剖析和事务方面的 。

Spring提供两种方式的编程式事务管理:
1、使用 TransactionTemplate
2、直接使用一个 PlatformTransactionManager 实现
如果你选择编程式事务管理,Spring小组推荐使用 TransactionTemplate。 第二种方法则类似使用JTA的 UserTransaction API

TransactionTemplate 它使用回调机制,将应用代码从样板式的资源获取和释放代码中解放出来, 这样写出的代码是目的驱动的,把精力集中在开发者想要做的事情上。
使用 TransactionTemplate 绝对会增加你的代码与Spring的事务框架和API间的耦合。

写一个 TransactionCallback 的实现, (通常会用匿名类来实现 )这样的实现会包含所以你需要在该事务上下文中执行的代码。
然后把一个实现TransactionCallback的实例传递给TransactionTemplate暴露的execute(..) 方法。
return transactionTemplate.execute(new TransactionCallback() {
// the code in this method executes in a transactional context
public Object doInTransaction(TransactionStatus status) {
updateOperation1();
return resultOfUpdateOperation2();
}
});
如果不需要返回值,更方便的方式是创建一个 TransactionCallbackWithoutResult 的匿名类,如下:
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(TransactionStatus status) {
updateOperation1();
updateOperation2();
}
});
回调方法内的代码可以通过调用 TransactionStatus 对象的 setRollbackOnly() 方法来回滚事务。

诸如传播模式、隔离等级、超时等等的事务设置都可以在TransactionTemplate中或者通过配置或者编程式地实现。 TransactionTemplate实例默认继承了默认事务设置。

TransactionTemplate 类的实例是线程安全的,任何状态都不会被保存。

可以使用 org.springframework.transaction.PlatformTransactionManager 来直接管理你的事务。
只需通过bean的引用,简单的把你在使用的PlatformTransactionManager 传递给你的bean。
然后,使用TransactionDefinition和TransactionStatus对象, 你可以启动,回滚和提交事务。

只有编程式事务管理才能显式的设置事务名称。

分享到:
评论

相关推荐

    Spring事务管理Demo

    Spring事务管理的目的是确保数据的一致性和完整性,尤其是在多操作、多资源的环境中。本Demo将深入探讨Spring如何实现事务的管理。 首先,Spring提供了两种主要的事务管理方式:编程式事务管理和声明式事务管理。 ...

    Spring事务管理开发必备jar包

    本资源包提供了进行Spring事务管理开发所需的所有关键库,包括框架基础、核心组件、AOP(面向切面编程)支持、日志处理、编译工具以及与数据库交互的相关jar包。下面将对这些知识点进行详细解释: 1. **Spring框架*...

    spring事务管理

    ### Spring事务管理详解 #### 一、Spring事务管理概述 Spring框架提供了强大的事务管理功能,使得开发者能够更方便地管理应用程序中的事务。Spring事务管理主要包括两种类型:编程式事务管理和声明式事务管理。 -...

    spring 事务管理的理解

    Spring 框架是Java开发中...理解并熟练掌握Spring事务管理,对于提升应用程序的稳定性和可靠性至关重要。在实际开发中,结合声明式事务管理、事务传播行为、隔离级别和回滚规则,可以有效地确保数据的完整性和一致性。

    Spring事务管理.pdf

    Spring事务管理.pdf 1.资料 2.本地事务与分布式事务 3.编程式模型 4.宣告式模型

    Synchronized锁在Spring事务管理下线程不安全

    Synchronized锁在Spring事务管理下,导致线程不安全。

    Spring事务管理的jar包

    本篇将深入探讨Spring事务管理的核心概念、工作原理以及如何使用`spring-tx-3.2.0.RELEASE.jar`这个jar包。 首先,我们需要理解什么是事务。在数据库系统中,事务是一组操作,这些操作被视为一个整体,要么全部完成...

    Spring事务管理失效原因汇总

    标题“Spring事务管理失效原因汇总”指出了本文的核心内容是分析在使用Spring框架进行事务管理时可能遇到的问题及其原因。描述部分进一步说明了事务失效的后果往往不明显,容易在测试环节被忽略,但在生产环境中出现...

    spring事务管理5种方法

    本篇文章将深入探讨Spring事务管理的五种方法,旨在帮助开发者更好地理解和运用这一核心特性。 首先,我们来了解什么是事务。在数据库操作中,事务是一组逻辑操作,这些操作要么全部成功,要么全部失败,确保数据的...

    Spring事务管理4种方式

    本文将详细介绍Spring事务管理的四种方式:编程式事务管理、声明式事务管理、PlatformTransactionManager接口以及TransactionTemplate。 1. **编程式事务管理**:这是一种手动控制事务的方式,通过在代码中调用`...

    详细介绍Spring事务管理

    ### Spring事务管理详解 #### 一、Spring事务管理的重要性及必要性 在现代软件开发中,事务管理是一项至关重要的技术,特别是在涉及数据库操作时。事务能够确保一系列操作要么全部成功,要么全部失败,这对于保持...

    spring事务管理.rar

    Spring事务管理是Spring框架的核心特性之一,它提供了一种强大且灵活的方式来管理应用程序中的事务边界。在企业级Java应用中,事务处理是确保数据一致性、完整性和可靠性的关键部分。本篇文章将深入探讨Spring的事务...

    spring事务管理.doc

    总的来说,Spring事务管理提供了一种灵活、强大的方式来处理应用程序中的事务,无论是在简单还是复杂的事务场景下,都能有效保证数据的一致性和完整性。通过声明式事务管理,开发者可以将关注点从事务细节中解脱出来...

    Spring事务管理

    Spring事务管理是Spring框架的核心特性之一,它提供了一种在Java应用中管理和协调数据库事务的标准方式。对于有Java基础的开发者来说,理解并掌握Spring事务管理至关重要,因为这有助于确保数据的一致性和完整性,...

    Spring事务管理配置文件问题排查

    当出现像描述中那样的问题——SQL语句执行出错但事务未回滚时,我们需要深入理解Spring事务管理的配置和机制。以下是一些关键知识点: 1. **Spring事务管理类型**: - **编程式事务管理**:通过`...

    spring事务管理几种方式代码实例

    spring事务管理几种方式代码实例:涉及编程式事务,声明式事务之拦截器代理方式、AOP切面通知方式、AspectJ注解方式,通过不同方式实例代码展现,总结spring事务管理的一般规律,从宏观上加深理解spring事务管理特性...

    Spring事务管理和SpringJDBC思维导图

    在思维导图"Spring Transaction.twd"中,可能包含了Spring事务管理的各个概念和它们之间的关系,如事务的ACID属性(原子性、一致性、隔离性和持久性),事务管理器,以及声明式和编程式事务管理的实现方式。...

    Spring事务管理的方法

    ### Spring事务管理的方法 #### 一、引言 在企业级应用开发中,事务管理是一项至关重要的技术。Spring框架作为Java领域中一个非常流行的轻量级框架,为开发者提供了多种方式来实现事务管理,其中主要分为编程式...

Global site tag (gtag.js) - Google Analytics