TransactionDefinition接口

16.2.1 探索TransactionDefinition接口

正如之前所说的,TransactionDefinition接口控制着事务的属性。下面让我们进一步看看该接口及其方法,如代码清单16-1所示:

代码清单16-1 TransactionDefinition接口

 

接口中简单而明显的方法是getTimeout()方法,它返回一个事务必须完成的时间限制(以秒为单位),还有isReadOnly()方法,它表示事务是否只读。事务管理器的实现可以利用这个值来优化事务的执行,并确保事务只进行读取操作。

另外两个方法--getPropagationBehavior()与getIsolationLevel()需要深入讨论。我们先介绍getIsolationLevel(),它对其他事务所能看到的数据变化进行控制。表16-1列出了你可以使用的事务隔离级别,并说明了其他事务可以访问的当前事务变化。

表16-1 事务隔离级别


隔离级别


说明


TransactionDefinition.

 ISOLATION_DEFAULT


PlatformTransactionManager

的默认隔离级别(对大多数数据库

来说就是ISOLATION_ READ_COMMITTED)


TransactionDefinition. ISOLATION_READ_UNCOMMITTED


最低的隔离级别。事实上我们不应该

称其为隔离级别,因为在事务完成前,

其他事务可以看到该事务所修改的数据。

而在其他事务提交前,该事务也可以看到

其他事务所做的修改


TransactionDefinition. ISOLATION_READ_COMMITTED


大多数数据库的默认级别。在事务完成前,

其他事务无法看到该事务所修改的数据。

遗憾的是,在该事务提交后,你就可以查

看其他事务插入或更新的数据。这意味

着在事务的不同点上,如果其他事务修改

了数据,你就会看到不同的数据


TransactionDefinition. ISOLATION_REPEATABLE_READ


比ISOLATION_READ_COMMITTED更严格,

该隔离级别确保如果在事务中查询了某个

数据集,你至少还能再次查询到相同的数

据集,即使其他事务修改了所查询的数据。

然而如果其他事务插入了新数据,

你就可以查询到该新插入的数据


TransactionDefinition. ISOLATION_SERIALIZABLE


代价最大、可靠性最高的隔离级别,

所有的事务都是按顺序一个接一个地执行

选择合适的隔离级别对于保证数据的一致性非常重要,并且所作出的选择会对性能产生重大影响。最高的隔离级别TransactionDefinition.ISOLATION_SERIALIZABLE开销最大。

getPropagationBehavior()方法指定了当代码请求一个新的事务时Spring所做的事情。表16-2列出了这个方法的常量值。

表16-2 传播行为值


传播行为


说明


TransactionDefinition. 

PROPAGATION_REQUIRED


当前如果有事务,Spring就会使用该事务;

否则会开始一个新事务


TransactionDefinition. 

PROPAGATION_SUPPORTS


当前如果有事务,Spring就会使用该事务;

否则不会开始一个新事务


TransactionDefinition. 

PROPAGATION_MANDATORY


当前如果有事务,Spring就会使用该事务;

否则会抛出异常


TransactionDefinition. PROPAGATION_REQUIRES_NEW


Spring总是开始一个新事务。如果当

前有事务,则该事务挂起


TransactionDefinition. PROPAGATION_NOT_SUPPORTED


Spring不会执行事务中的代码。代码总

是在非事务环境下执行,如果当前

有事务,则该事务挂起


TransactionDefinition. 

PROPAGATION_NEVER


即使当前有事务,Spring也会在非

事务环境下执行。如果当前有事务,

则抛出异常


TransactionDefinition. 

PROPAGATION_NESTED


如果当前有事务,则在嵌套

事务中执行。如果没有,那么

执行情况

Transaction- Definition.

PROPAGATION_REQUIRED一样

16.2.2 使用TransactionStatus接口

如代码清单16-2所示,TransactionStatus接口可以让事务管理器控制事务的执行,可以检查事务是不是一个新事务,或者是否只读。TransactionStatus还可以初始化回滚操作。

代码清单16-2 TransactionStatus 声明

TransactionStatus接口中的方法很容易理解;最引人注目的就是setRollbackOnly(),它将一个事务标识为不可提交的。换句话说,在调用完setRollbackOnly()后你所能执行的唯一操作就是回滚。在大多数情况下,事务管理器会检测到这一点,在它发现事务要提交时会立刻结束事务。代码清单16-3中的伪代码说明了这一点。

代码清单16-3 setRollbackOnly()方法的使用

在调用完setRollbackOnly()后,大多数数据库可以继续执行下一条select语句,但不允许执行update语句--执行update是没有意义的,因为事务只可以进行读取操作,任何修改都不会被提交。

16.2.3 PlatformTransactionManager的实现

PlatformTransactionManager接口使用TransactionDefinition和TransactionStatus接口,创建并管理事务。该接口的实现必须对事务管理器有深入理解。DataSourceTransactionManager控制着从DataSource中获得的JDBC Connection上的事务的执行;HibernateTransactionManager控制着Hibernate session上的事务的执行;JdoTransactionManager管理着JDO事务;JtaTransactionManager将事务管理委托给JTA。

16.3 对一个事务管理示例的探索(1)

本章的第一部分已经对Spring中的事务基础架构进行了概览,但我们认为,仍然需要给出一个能说明如何使用Spring的事务支持的示例。

使用事务操作的方式有3种基本方式:可以使用声明式事务,只需声明某个方法需要事务就行了;可以使用源码级的元素据来说明某个方法需要一个事务;还可以用编写事务代码的方式来实现。Spring对这3种方式都提供了支持,我们从最灵活最方便的方式开始,即声明式事务管理。

首先我们将展示几种事务支持的实现方式。浏览一下图16-1中的UML类图,对该示例应用中需要保存的数据有一个直观印象。

尽管该类图看起来有些复杂,但我们只是实现一个简单的银行应用程序。我们有一个用来维护账户余额的Account类(这是真实银行账户的简化版,但对于示例来说足够用了)。我们将AccountIdentity作为银行账户的唯一标识。BalanceMutator接口只有一个mutate(BigDecimal)方法,我们在BankService- Support中实现该接口。CreditBalanceMutator将贷款数额加到了balance参数中。DebitBalanceMutator稍微有点复杂,它检查账户中是否有足够的钱可以借出。若想进一步探究这个概念,例如可以修改DebitBalanceMutator以允许透支。

AccountDao定义了一个数据访问接口,该接口由JdbcAccountDao类实现。接下来,我们在BankService接口中定义了transfer和getBalance方法。BankServiceSupport实现了这两个方法,它用两个以do开头的protected方法进行实现。我们将使用BankServiceSupport子类来演示各种不同的事务管理技术。

(点击查看大图)图16-1 带有事务的银行应用示例的UML类图

非事务性代码

在讨论事务管理之前,我们得编写必要的支持代码。让我们以代码清单16-4中的SQL代码开始吧,这些代码创建了t_account表并插入几个测试账户。

代码清单16-4 样例账户应用的SQL 代码

这些SQL代码没什么特别的。如果你没有使用Oracle 10g数据库,那么你可能需要修改一下SQL语法使之适合你的数据库。接下来,我们看看Account与AccountIdentity类及BalanceMutator接口。我们在代码清单16-5中列出了这几个类和接口的代码。

代码清单16-5 Account、AccountIdentity和BalanceMutator

你可以看到Account类有一个我们赋予的识别器(Long id)。该识别器就是实现的细节问题了:我们的代码需要这个ID,但它对用户来说是没有任何意义的。用户使用账户号和分类号来标识其账户。Account类只有一个重要的方法:changeBalance(BalanceMutator)。这个方法使用BalanceMutator实例来更新账户的余额。

说明 我们选择使用BalanceMutator来更新账户的余额,因为我们觉得管理余额的规则可能会非常复杂。使用一个接口(该接口在服务层实现)会比在Account类中简单地定义credit(BigDecimal)和debit(BigDecimal)方法更灵活。

接下来,我们看看该示例应用的数据访问层。简单起见,我们使用SimpleJdbcTemplate(请查看第9章以了解关于Spring JDBC支持的详细内容)。我们采取了Spring应用所使用的一种典型方式:创建AccountDao接口及其实现--JdbcAccountDao。代码清单16-6列出了接口和实现的源代码。

代码清单16-6 AccountDao接口和JdbcAccountDao实现

我们尽量保持代码的简单性。记住我们并不是在展示Spring JDBC,而仅仅是实现数据访问层代码以说明Spring的事务管理。最后,我们实现了BankServiceSupport,将该类作为事务性的BankService实现的父类。这样,BankServiceSupport就用以do开头的protected方法去实现BankService中的方法。代码清单16-7显示了BankServiceSupport的实现。

代码清单16-7 BankServiceSupport代码

时间: 2024-10-10 03:22:53

TransactionDefinition接口的相关文章

Spring事务管理(详解+实例)

写这篇博客之前我首先读了<Spring in action>,之后在网上看了一些关于Spring事务管理的文章,感觉都没有讲全,这里就将书上的和网上关于事务的知识总结一下,参考的文章如下: Spring事务机制详解 Spring事务配置的五种方式 Spring中的事务管理实例详解 1 初步理解 理解事务之前,先讲一个你日常生活中最常干的事:取钱. 比如你去ATM机取1000块钱,大体有两个步骤:首先输入密码金额,银行卡扣掉1000元钱:然后ATM出1000元钱.这两个步骤必须是要么都执行要么都

Spring 框架之九阴真经

Chapter One . Spring 事务配置 1.事务(Transaction)是并发控制的单位,是用户定义的一个操作序列. 这些操作要么都做,要么都不做,是一个不可分割的工作单位.通过事务,SQL Server能将逻辑相关的一组操作绑定在一起,以便服务器保持数据的完整性. 事务通常是以Begin,Transaction 开始,以Commit或Rollback结束. Commit:表示提交,即提交事务的所有操作.具体地说就是将事务中所有对数据库的更新写回到磁盘上的物理数据库中去,事务正常结

spring ----编程式事务和声明式事务

一. 事务 事务管理对于企业应用而言是非常重要的,事务的存在保证了用户的每一次操作都是可靠的,当用户操作出现异常时也不至于破坏了后台的数据.例如银行的自动取款机,万一你在转账的时候出现了异常,事务机制会保证你后台的数据还是出异常操作之前的数据,也就是是你出异常的这些操作失效. 事务就是一组由于逻辑上紧密关联而合并成一个整体(工作单元)的多个数据库操作,这些操作要么都执行,要么都不执行. 银行转账操作:开启事务,就是保证转账的操作要么都执行,要么都不执行. 如果在你的账户减去转账金额后出现异常,不

Spring事务管理

写这篇博客之前我首先读了<spring in action>,之后在网上看了一些关于Spring事务管理的文章,感觉都没有讲全,这里就将书上的和网上关于事务的知识总结一下,参考的文章如下: Spring事务机制详解 Spring事务配置的五种方式 Spring中的事务管理实例详解 1 初步理解 理解事务之前,先讲一个你日常生活中最常干的事:取钱. 比如你去ATM机取1000块钱,大体有两个步骤:首先输入密码金额,银行卡扣掉1000元钱:然后ATM出1000元钱.这两个步骤必须是要么都执行要么都

Java之Spring知识点

1.AOP的概念是Aspected Oriented Programming 面向方面编程. 好处:AOP将程序分解成各个方面或者说关注点.这使得可以模块化,相当横向上分切了.它可以解决OOP和过程化方法不能够很好解决的横切(crosscut)问题,如:事务.安全.日志等横切关注 实现AOP有几种方式: 1. Spring 1.2版本中通过ProxyFactoryBean来实现aop,即通过动态代理来实现的,Aspect必须继承MethodBeforeAdvice,MethodAfterAdvi

Spring五个事务隔离级别和七个事务传播行为

1. 脏读 :脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据. 2. 不可重复读 :是指在一个事务内,多次读同一数据.在这个事务还没有结束时,另外一个事务也访问该同一数据.那么,在第一个事务中的两 次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的.这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不 可重复读.例如,一个编辑人员两次读取同一文档,但在两次读取之间

[转]Spring3核心技术之事务管理机制

原文地址:http://chouyi.iteye.com/blog/1675199 Spring对事务的解决办法其实分为2种:编程式实现事务,AOP配置声明式解决方案. http://jinnianshilongnian.iteye.com/blog/1496953 Spring提供了许多内置事务管理器实现,常用的有以下几种: DataSourceTransactionManager:位于org.springframework.jdbc.datasource包中,数据源事务管理器,提供对单个ja

Spring事务:传播行为与隔离级别

文章主要来源:https://github.com/dengdaiyemanren/onetopiconeday/wiki/spring%E4%BA%8B%E5%8A%A1%E9%85%8D%E7%BD%AE 传播行为 在TransactionDefinition接口中定义了七个事务传播行为:PROPAGATION_REQUIRED:支持当前事务,如果当前没有事务,就新建一个事务.这是最常见的选择.PROPAGATION_SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行.PR

事务的作用以及了解(原文来源于其他博文)

首先,说说什么事务 (Transaction). 事务,就是一组操作数据库的动作集合. 事务是现代数据库理论中的核心概念之一.如果一组处理步骤或者全部发生或者一步也不执行,我们称该组处理步骤为一个事务.当所有的步骤像一个操作一样被完整地执行,我们称该事务被提交.由于其中的一部分或多步执行失败,导致没有步骤被提交,则事务必须回滚到最初的系统状态. 事物的基本特征: 事务是并发控制的单位,是用户定义的一个操作序列.这些操作要么都做,要么都不做,是一个不可分割的工作单位.通过事务,SQL Server