详解spring事务属性

详解spring事务属性
详解spring事务属性

事务是什么?

事务像1个原子,1个事务中的操作要么全部执行,要么就不要执行,它就应当是执行的最小单元;

事务的特点

* atomicity 原子性,事务是1个不可分割的工作单元

* consistency 一致性,事务所完成的工作后,各有关系的部分应当是协调一致的,就像买东西一样,事务应当包含付款和取货,而不能只包含其中1个;

* isolation 隔离性,1个事务执行期间不能受其它事务干扰,即 1个事务的操作和使用的数据对同时发生的其它事务应当是隔离的,即避免资源使用的冲突;

*durability 永久性,事务成功完成后,它产生的影响就不再回滚了;

关键字: spring事务

Spring事务-(1)2008-07-25 11:37Spring事务-(1)Spring的事务管理是其非常重要的一个方

面,Spring的应用主要集中在Ioc/AOP/DAO/事务四个方面。这部分内容比较抽象,需要花费大篇幅来写。

一、事务控制的基本知识不管是什么事务,必须先对数据库的事务概念有个明确认识才行。首先先简单介

绍下数据库的事务。事务的概念:事务是一组原子性操作的工作单元,这组工作单元要么执行成功,要么

不成功。事务有四个属性--原子性、一致性、独立性和持久性(CAID),所有这些方面都是依靠事务资源

去维护。事务隔离:SQL 标准用三个必须在并行的事务之间避免的现象定义了四个级别的事务隔离。这些

不希望发生的现象是:脏读(dirty reads)一个事务读取了另一个未提交的并行事务写的数据。不可重

复读(non-repeatable reads)一个事务重新读取前面读取过的数据,发现该数据已经被另一个已提交

的事务修改过。幻读(phantom read)一个事务重新执行一个查询,返回一套符合查询条件的行,发现

这些行因为其他最近提交的事务而发生了改变。这四种隔离级别和对应的行为如下表:

隔离级别脏读(Dirty Read)不可重复读(NonRepeatable Read)幻读(Phantom

Read)

读未提交(Read uncommitted)可能可能可能读已提交(Read committed)不可能可能可能

可重复读(Repeatable read)不可能不可能可能

可串行化(Serializable )不可能不可能不可能Spring事务包中的TransactionDefinition接口有对应的隔离级别的定义。高清楚以上的概念,才能更好

理解Spring的事务管理。二、从编程的角度认识事务和数据库事务概念几乎完全一样:事务是一种机制,

把组成的多个操作视为一个操作单元进行处理,这个单元要么全部执行成功,要么全部不执行。在事务中

,涉及的操作可能依赖于很多不同的数据库和服务器。从程序角度考虑,事务可以分为两大类:一种是本

地事务,一种是全局事务(也叫分布式事务)。本地事务:是针对某个独立的事务资源(如JDBC)操作的

事务。全局事务:是协同或横跨多个资源(如JDBC连接、数据库等)操作的事务(上下文),多个资源协

作是由事务管理器来完成的。事务源:是可以绑定事务操作的资源。事务的概念最初来自数据库的操作,

事务的资源也仅限于数据库。但编程中的事务,事务源很广泛,不但可以包含数据库,还可以包含打印机

等。本地事务和全局事务有很大的区别:全局事务的控制非常复杂,全局事务使用两阶段提交协议(2PC)来

提交资源源的变化。阶段一请求所有资源准备实现改变;阶段二请求做实际的改变。

全局事务ID(XID)是用于跟踪所有分布式事务相关的改变。全局事务的实现需要由专门的应用服务器或者

容器去实现。在Java中,可以借助实现了Java Transaction API的库来进行全局事务控

制。JDBC与JTAJDBC是Java database connectivity 的缩写,意思是Java数据库连接。一般本地事务是

与一个数据库连接相关的,因此Java中常称本地事务为JDBC事务。JDBC本身提供了简单的本地事务控制,

可以满足针对一个JDBC连接事务的需求。JTA是Java Transaction API的缩写,意思是Java 事务API,这

是一种组复杂事务控制接口,这组接口作为J2EE规范暴露给容器开发商,一般都由J2EE 容器来实

现。Spring很牛,也实现了这组API,使得任何应用使用JTA事务变得更容易。三、认识Spring的事务包的

APISpring对事务的控制的API全部位于org.springframework.transaction包下面,其中出去异常定义

的类外,仅有四个接口,这四个接口是Spring操作事务的核心,下面一一介

绍:org.springframework.transactionInterfaces PlatformTransactionManager

SavepointManager

TransactionDefinition

TransactionStatus

Exceptions :

CannotCreateTransactionException

HeuristicCompletionException

IllegalTransactionStateException

InvalidIsolationLevelException

InvalidTimeoutException

NestedTransactionNotSupportedException

NoTransactionException

TransactionException

TransactionSuspensionNotSupportedException TransactionSystemException

TransactionTimedOutException

TransactionUsageException

UnexpectedRollbackException

要搞明白Spring事务控制的原理,必须理解上面四个接口的含义,下面一一介绍之。

1、PlatformTransactionManager是一个事务管理平台,该接口有许多具体的事务实现类,例

如DataSourceTransactionManager, HibernateTransactionManager, JdoTransactionManager,

JmsTransactionManager, JpaTransactionManager, JtaTransactionManager,

TopLinkTransactionManager, WebLogicJtaTransactionManager 等等,通过实现此接口,

Spring可以

管理任何实现了这些接口的事务。开发人员也可以使用统一的编程模型来控制管理事务。此

接口中有三个

方法:void commit(TransactionStatus status) Commit the given transaction,

with

regard to its status. 监视事务状态,并提交一个事务。TransactionStatus

getTransaction(TransactionDefinition definition) Return a currently

active

transaction or create a new one, according to the specified propagation behavior.

根据事务的隔离级别和传播行为,返回当前活动的事务或者产生一个新的事务。void

rollback(TransactionStatus status) Roll back the given transaction. 回滚给定的事务。

2、SavepointManager事务回滚点管理接口,提供创建、释放回滚点,或者回滚到指定的回

滚点。方法摘

要:Object createSavepoint() Create a new savepoint. 创建一个

新的回滚点

。void releaseSavepoint(Object savepoint) Explicitly release the given

savepoint. 释放一个给定的回滚点。void rollbackToSavepoint(Object

savepoint)

Roll back to the given savepoint. 回滚到给定的回滚点。

3、TransactionDefinition这个接口的作用就是定义事务的名称、隔离级别、传播行为、

超时时间长短、

只读属性等。字段摘要:(因为是接口,里面都是int常量,即public static final类型

的,很多,我就

只写常量的名字和含义)这些接口分两组,分别是事务隔离级别和事务传播行为。//事务隔离级别(数据库

级别的知识) TransactionDefinition.ISOLATION_DEFAULT使用底层数据库默认隔离级

别。TransactionDefinition.ISOLATION_READ_UNCOMMITTED 读未提交最低隔离等级,允许事务读取其

他并行的事务还没有提交的数据,会发生脏读(dirty reads)、不可重复读(non-repeatable reads)

、幻读(phantom read)等问题。TransactionDefinition.ISOLATION_READ_COMMITTED 读已提交允许

事务读取其他并行的事务已经提交的数据,可以防止脏读问

题。TransactionDefinition.ISOLATION_REPEATABLE_READ 可重复读保证了一个事务不会修改已经由另

一个事务读取但未提交(回滚)的数据。TransactionDefinition.ISOLATION_SERIALIZABLE 可串行化

所有事务都严格隔离,各个事务顺序执行。很容易发生死锁。//事务传播行

为TransactionDefinition.PROPAGATION_REQUIRED支持现有的事务,如果没有则新建一个事

务。TransactionDefinition.PROPAGATION_SUPPORTS支持现有的事务,如果没有则以非事务状态运行。

TransactionDefinition.PROPAGATION_MANDATORY支持现有事务,如果没有则抛出异

常。TransactionDefinition.PROPAGATION_REQUIRES_NEW总是发起一个新事务。如果当前已存在一个事

务,则将其挂起。TransactionDefinition.PROPAGATION_NOT_SUPPORTED不支持事务,总是以非事务状

态运行,如果当前存在一个事务,则将其挂起。TransactionDefinition.PROPAGATION_NEVER 不支持事务

,总是以非事务状态运行,如果当前存在一个事务,则抛出异

常。TransactionDefinition.PROPAGATION_NESTED如果石阡已经存在一个事务,则以嵌套

事务的方式运

行,如果当前没有事务,则创建一个新事务。方法摘要:int getIsolationLevel()

Return

the isolation level. 返回事务的隔离级别。String getName()

Return the

name of this transaction. 返回事务的名字。int getPropagationBehavior() Return the propagation behavior. 返回事务的是传播行为。int getTimeout() Return the transaction timeout. 返回事务的超时时间。boolean isReadOnly()

Return whether to optimize as read-only transaction. 返回是否(优化为)

只读属性

4、TransactionStatus 这个接口的作用就是获取事务的状态(回滚点、是否完成、是否新

事物、是否回

滚)属性,还可以进行事务rollback-only的设置。方法摘要:boolean hasSavepoint()

Return whether this transaction internally carries a savepoint, i.e. has been

created

as nested transaction based on a savepoint. 判断这个事务是否有一个内在

的回滚

点(savepoint),即创建为基于回滚点的嵌套事务。boolean isCompleted()

Return

whether this transaction is completed, that is, has already been committed or rolled

back. 判断这个事务是否完成,也就是已经提交或者回滚。boolean

isNewTransaction()

Return if the transaction is new, else participating in an existing

transaction.

判断一个事物是否为新事务,或者是这个事务参与到一个已经存在的事务里面。

boolean

isRollbackOnly() Return if the transaction has been set rollback-only.

判断这个事务是否已经设置了rollback-only。void setRollbackOnly() Set

the

transaction rollback-only. 设置这个事务rollback-only。

详解spring事务属性

Spring声明式事务让我们从复杂的事务处理中得到解脱。使得我们再也无需要去处理获得

连接、关闭连接、事务提交和回滚等这些操作。再也无需要我们在与事务相关的方法中处理

大量的try…catch…finall y代码。

我们在使用Spring声明式事务时,有一个非常重要的概念就是事务属性。事务属性通常由

事务的传播行为,事务的隔离级别,事务的超时值和事务只读标志组成。我们在进行事务划

分时,需要进行事务定义,也就是配置事务的属性。

Spring在TransactionDefinition接口中定义这些属性,以供

PlatfromTransactionManager使用, PlatfromTransactionManager是spring事务管理的核

心接口。

Java代码

1.TransactionDefinition

2.public interface TransactionDefinition {

3. int getPropagationBehavior();

4. int getIsolationLevel();

5. int getTimeout();

6. boolean isReadOnly();

7.}

getTimeout()方法,它返回事务必须在多少秒内完成。

isReadOnly(),事务是否只读,事务管理器能够根据这个返回值进行优化,确保事务是只读

的。

getIsolationLevel()方法返回事务的隔离级别,事务管理器根据它来控制另外一个事务可

以看到本事务内的哪些数据。

在TransactionDefinition接口中定义了五个不同的事务隔离级别

ISOLATION_DEFAULT 这是一个PlatfromTransactionManager默认的隔离级别,使用数据库

默认的事务隔离级别.另外四个与JDBC的隔离级别相对应

ISOLATION_READ_UNCOMMITTED这是事务最低的隔离级别,它充许别外一个事务可以看到这

个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻像读。

例如:

Mary的原工资为1000,财务人员将Mary的工资改为了8000,但未提交事务

Java代码

1.Connection con1 = getConnection();

2.con.setAutoCommit(false);

3.update employee set salary = 8000 where empId ="Mary";

与此同时,Mary正在读取自己的工资

Java代码

1.Connection con2 = getConnection();

2.select salary from employee where empId ="Mary";

https://www.360docs.net/doc/812877340.html,mit();

Mary发现自己的工资变为了8000,欢天喜地!

而财务发现操作有误,而回滚了事务,Mary的工资又变为了1000

Java代码

1.//con1

2. con1.rollback();

像这样,Mary记取的工资数8000是一个脏数据。

ISOLATION_READ_COMMITTED 保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据。这种事务隔离级别可以避免脏读出现,但是可能会出现不可重复读和幻像读。

ISOLATION_REPEATABLE_READ 这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免下面的情况产生(不可重复读)。

在事务1中,Mary 读取了自己的工资为1000,操作并没有完成

Java代码

1.con1 = getConnection();

2.select salary from employee empId ="Mary";

在事务2中,这时财务人员修改了Mary的工资为2000,并提交了事务.

Java代码

1.con2 = getConnection();

2.update employee set salary = 2000;

https://www.360docs.net/doc/812877340.html,mit();

在事务1中,Mary 再次读取自己的工资时,工资变为了2000

Java代码

1.//con1

2.select salary from employee empId ="Mary";

在一个事务中前后两次读取的结果并不致,导致了不可重复读。

使用ISOLATION_REPEATABLE_READ可以避免这种情况发生。

ISOLATION_SERIALIZABLE 这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。除了防止脏读,不可重复读外,还避免了幻像读。

目前工资为1000的员工有10人。

事务1,读取所有工资为1000的员工。

Java代码

1.con1 = getConnection();

2.Select * from employee where salary =1000;

共读取10条记录

这时另一个事务向employee表插入了一条员工记录,工资也为1000

Java代码

1.con2 = getConnection();

2.Insert into employee(empId,salary) values("Lili",1000);

https://www.360docs.net/doc/812877340.html,mit();

事务1再次读取所有工资为1000的员工

Java代码

1.//con1

2.select * from employee where salary =1000;

共读取到了11条记录,这就产生了幻像读。

ISOLATION_SERIALIZABLE能避免这样的情况发生。但是这样也耗费了最大的资源。

getPropagationBehavior()返回事务的传播行为,由是否有一个活动的事务来决定一个事务调用。

在TransactionDefinition接口中定义了七个事务传播行为。

PROPAGATION_REQUIRED 如果存在一个事务,则支持当前事务。如果没有事务则开启一个新的事务。

Java代码

1.//事务属性 PROPAGATION_REQUIRED

2.methodA{

3.……

4.methodB();

5.……

6.}

7.

8.//事务属性 PROPAGATION_REQUIRED

9.methodB{

10.……

11.}

使用spring声明式事务,spring使用AOP来支持声明式事务,会根据事务属性,自动在方法调用之前决定是否开启一个事务,并在方法执行之后决定事务提交或回滚事务。

单独调用methodB方法

Java代码

1.main{

2. metodB();

3.}

相当于

Java代码

1.Main{

2.Connection con=null;

3.

4. rry{

5. con = getConnection();

6. con.setAutoCommit(false);

7.//方法调用

8.methodB();

9.//提交事务

https://www.360docs.net/doc/812877340.html,mit();

11.}

12.Catch(RuntimeException ex){

13. //回滚事务

14. con.rollback();

15.}

16.finally{

17. //释放资源

18. closeCon();

19.}

20.}

Spring保证在methodB方法中所有的调用都获得到一个相同的连接。在调用methodB时,没有一个存在的事务,所以获得一个新的连接,开启了一个新的事务。

单独调用MethodA时,在MethodA内又会调用MethodB.

执行效果相当于

Java代码

1.main{

2. Connection con = null;

3. try{

4. con = getConnection();

5. methodA();

6. https://www.360docs.net/doc/812877340.html,mit();

7.}

8.cathc(RuntimeException ex){

9. con.rollback();

10.}

11.finally{

12. closeCon();

13.}

14.}

调用MethodA时,环境中没有事务,所以开启一个新的事务.

当在MethodA中调用MethodB时,环境中已经有了一个事务,所以methodB就加入当前事务。

PROPAGATION_SUPPORTS 如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行。但是对于事务同步的事务管理器,PROPAGATION_SUPPORTS与不使用事务有少许不同。

Java代码

1.//事务属性 PROPAGATION_REQUIRED

2.methodA(){

3. methodB();

4.}

5.

6.//事务属性 PROPAGATION_SUPPORTS

7.methodB(){

8.……

9.}

单纯的调用methodB时,methodB方法是非事务的执行的。

当调用methdA时,methodB则加入了methodA的事务中,事务地执行。

PROPAGATION_MANDATORY 如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。

Java代码

1.//事务属性 PROPAGATION_REQUIRED

2.methodA(){

3. methodB();

4.}

5.

6.//事务属性 PROPAGATION_MANDATORY

7.methodB(){

8.……

9.}

当单独调用methodB时,因为当前没有一个活动的事务,则会抛出异常

throw new IllegalTransactionStateException("Transaction propagation 'mandatory' but no existing transaction found");

当调用methodA时,methodB则加入到methodA的事务中,事务地执行。

PROPAGATION_REQUIRES_NEW 总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。

Java代码

1.//事务属性 PROPAGATION_REQUIRED

2.methodA(){

3. doSomeThingA();

4.methodB();

5.doSomeThingB();

6.}

7.

8.//事务属性 PROPAGATION_REQUIRES_NEW

9.methodB(){

10.……

11.}

当单独调用methodB时,相当于把methodb声明为REQUIRED。开启一个新的事务,事务地执行。

当调用methodA时

Java代码

1.main(){

2. methodA();

3.}

情况有些大不一样.相当于下面的效果。

Java代码

1.main(){

2. TransactionManager tm = null;

3.try{

4. //获得一个JTA事务管理器

5. tm = getTransactionManager();

6. tm.begin();//开启一个新的事务

7. Transaction ts1 = tm.getTransaction();

8. doSomeThing();

9. tm.suspend();//挂起当前事务

10. try{

11. tm.begin();//重新开启第二个事务

12. Transaction ts2 = tm.getTransaction();

13. methodB();

14. https://www.360docs.net/doc/812877340.html,mit();//提交第二个事务

15.

16. }

17. Catch(RunTimeException ex){

18. ts2.rollback();//回滚第二个事务

19. }

20. finally{

21. //释放资源

22. }

23. //methodB执行完后,复恢第一个事务

24. tm.resume(ts1);

25.doSomeThingB();

26. https://www.360docs.net/doc/812877340.html,mit();//提交第一个事务

27.}

28.catch(RunTimeException ex){

29. ts1.rollback();//回滚第一个事务

30.}

31.finally{

32. //释放资源

33.}

34.}

在这里,我把ts1称为外层事务,ts2称为内层事务。从上面的代码可以看出,ts2与ts1是两个独立的事务,互不相干。Ts2是否成功并不依赖于ts1。如果methodA方法在调用methodB方法后的doSomeThingB方法失败了,而methodB方法所做的结果依然被提交。而除了methodB之外的其它代码导致的结果却被回滚了。

使用PROPAGATION_REQUIRES_NEW,需要使用JtaTransactionManager作为事务管理器。PROPAGATION_NOT_SUPPORTED总是非事务地执行,并挂起任何存在的事务。

Java代码

1.//事务属性 PROPAGATION_REQUIRED

2.methodA(){

3. doSomeThingA();

4.methodB();

5.doSomeThingB();

6.}

7.

8.//事务属性 PROPAGATION_NOT_SUPPORTED

9.methodB(){

10.……

11.}

当单独调用methodB时,不启用任何事务机制,非事务地执行。

当调用methodA时,相当于下面的效果

Java代码

1.main(){

2. TransactionManager tm = null;

3.try{

4. //获得一个JTA事务管理器

5. tm = getTransactionManager();

6. tm.begin();//开启一个新的事务

7. Transaction ts1 = tm.getTransaction();

8. doSomeThing();

9. tm.suspend();//挂起当前事务

10. methodB();

11. //methodB执行完后,复恢第一个事务

12. tm.resume(ts1);

13.doSomeThingB();

14. https://www.360docs.net/doc/812877340.html,mit();//提交第一个事务

15.}

16.catch(RunTimeException ex){

17. ts1.rollback();//回滚第一个事务

18.}

19.finally{

20. //释放资源

21.}

22.}

使用PROPAGATION_NOT_SUPPORTED,也需要使用JtaTransactionManager作为事务管理器。PROPAGATION_NEVER总是非事务地执行,如果存在一个活动事务,则抛出异常

Java代码

1.//事务属性 PROPAGATION_REQUIRED

2.methodA(){

3. doSomeThingA();

4.methodB();

5.doSomeThingB();

6.}

7.

8.//事务属性 PROPAGATION_NEVER

9.methodB(){

10.……

11.}

单独调用methodB,则非事务的执行。

调用methodA则会抛出异常

throw new IllegalTransactionStateException(

"Transaction propagation 'never' but existing transaction found");

PROPAGATION_NESTED如果一个活动的事务存在,则运行在一个嵌套的事务中. 如果没有活动事务, 则按TransactionDefinition.PROPAGATION_REQUIRED 属性执行

这是一个嵌套事务,使用JDBC 3.0驱动时,仅仅支持DataSourceTransactionManager作为事务管理器。需要JDBC 驱动的java.sql.Savepoint类。有一些JTA的事务管理器实现可能也提供了同样的功能。

使用PROPAGATION_NESTED,还需要把PlatformTransactionManager的nestedTransactionAllowed属性设为true;

而nestedTransactionAllowed属性值默认为false;

Java代码

1.//事务属性 PROPAGATION_REQUIRED

2.methodA(){

3. doSomeThingA();

4.methodB();

5.doSomeThingB();

6.}

7.

8.//事务属性 PROPAGATION_NESTED

9.methodB(){

10.……

11.}

如果单独调用methodB方法,则按REQUIRED属性执行。

如果调用methodA方法,相当于下面的效果

Java代码

1.main(){

2.Connection con = null;

3.Savepoint savepoint = null;

4.try{

5. con = getConnection();

6. con.setAutoCommit(false);

7. doSomeThingA();

8. savepoint = con2.setSavepoint();

9. try

10. methodB();

11. }catch(RuntimeException ex){

12. con.rollback(savepoint);

13. }

14. finally{

15. //释放资源

16. }

17.

18. doSomeThingB();

19. https://www.360docs.net/doc/812877340.html,mit();

20.}

21.catch(RuntimeException ex){

22. con.rollback();

23.}

24.finally{

25. //释放资源

26.}

27.}

当methodB方法调用之前,调用setSavepoint方法,保存当前的状态到savepoint。如果methodB方法调用失败,则恢复到之前保存的状态。但是需要注意的是,这时的事务并没有进行提交,如果后续的代码(doSomeThingB()方法)调用失败,则回滚包括methodB方法的所有操作。

嵌套事务一个非常重要的概念就是内层事务依赖于外层事务。外层事务失败时,会回滚内层事务所做的动作。而内层事务操作失败并不会引起外层事务的回滚。

PROPAGATION_NESTED 与PROPAGATION_REQUIRES_NEW的区别:它们非常类似,都像一个嵌套事务,如果不存在一个活动的事务,都会开启一个新的事务。使用

PROPAGATION_REQUIRES_NEW时,内层事务与外层事务就像两个独立的事务一样,一旦内层事务进行了提交后,外层事务不能对其进行回滚。两个事务互不影响。两个事务不是一个真正的嵌套事务。同时它需要JTA事务管理器的支持。

使用PROPAGATION_NESTED时,外层事务的回滚可以引起内层事务的回滚。而内层事务的异常并不会导致外层事务的回滚,它是一个真正的嵌套事务。DataSourceTransactionManager 使用savepoint支持PROPAGATION_NESTED时,需要JDBC 3.0以上驱动及1.4以上的JDK 版本支持。其它的JTA TrasactionManager实现可能有不同的支持方式。

PROPAGATION_REQUIRED应该是我们首先的事务传播行为。它能够满足我们大多数的事务需求。

spring配置文件各个属性详解

spring配置文件各个属性详解 分类:spring 2012-08-09 11:25 9316人阅读评论(2) 收藏举报springaophibernateattributesxhtmlwebsphere 目录(?)[+]一、引用外部属性文件 classpath:mail.properties classpath:jdbc.properties 我们定义了一个PropertyPlaceholderConfigurer类的实例,并将其位置属性设置为我们的属性文件。该类被实现为Bean工厂的后处理器,并将使用定义在文件中的属性来代替所有的占位符(${...}value)。 注意: 而在spring2.5的版本中提供了一种更简便的方式,如: 1. 这样以后要使用属性文件中的资源时,可以使用${属性名}来获得。 二、常用数据源的配置 第一种是:DBCP数据源,(需要加入2个jar文件,在spring中的lib下 jakarta-commons/commons-dbcp.jar和commons-pools.jar)主要配置如下:

spring使用基于注解的AOP事务管理

spring使用基于注解的AOP事务管理 16.6 AOP事务管理 AOP事务管理利用了Spring AOP的基础设施,在大多数情况下,Spring AOP会创建一个JDK代理以拦截方法调用。你可以使用装载时编织以在装载期编织切面,这样就不需要代理了(如果你记不清什么是装载时编织,请参看第6章)。你有两种方式来配置Spring AOP 事务管理,基于注解的配置以及XML配置。 16.6.1 使用基于注解的AOP事务管理 你可以借助于AOP的自动代理,通过注解将事务性行为引入到现有的bean中。让我们以代码清单16-21开始吧,它展示了类DeclarativeTxBankService。 代码清单16-21 DeclarativeTxBankService实现 请注意@Transactional属性,为了让Spring的事务管理基础设施可以利用该属性创建恰当的切入点和通知,我们需要使用AOP的自动代理和注解驱动的事务支持。代码清单16-22展示了与该注解相对应的XML配置。 代码清单16-22 基于注解的事务管理的配置文件

该XML配置文件展示了标准的bankService bean声明,紧跟其后的是 标签。 标签使用@Transactional注解创建恰当的事务管理切面。接下来由通知匹配的bean。 1.探索tx:annotation-driven标签 标签是注解驱动的事务管理支持的核心。表16-3列出了 标签的所有属性。 表16-3 标签的属性 属性说明 transactionManager 指定到现有的PlatformTransaction Manager bean的引用,通知会使用该引用 mode 指定Spring事务管理框架创建通知bean的方式。 可用的值有proxy和aspectj。前者是默认值, 表示通知对象是个JDK代理;后者表示 Spring AOP会使用AspectJ创建代理 order 指定创建的切面的顺序。只要目标对象有多个通知就可以使用该属性 proxy-target-class 该属性如果为true就表示你想要代理目标类而不是bean所实现的所有接口

S详细讲解SH中Spring事务流程

给你详细讲一下SSH框架的事物管理,希望对你有帮助。 Struts+hibernate+spring整合开发web应用是相当流行的,只需要简单的配置就能轻松的对数据库进行crud操作,下面就hibernate+spring 的配置做一下剖析,一边与大家一起分享经验: 1、准备工作: 可以利用hibernate tools生成相关映射文件已经po对象、dao对象,dao 也可以自己手动编写,无非就是实现crud,如果通过继承hibernate提供的HibernateDaoSupport,则可以更轻松的实现 关键就在于配置文件,下面看一个样例:

Spring分布式事务实现

Spring分布式事务实现 分布式事务是指操作多个数据库之间的事务,spring的org.springframework.transaction.jta.JtaTransactionManager,提供了分布式事务支持。如果使用WAS的JTA支持,把它的属性改为WebSphere对应的TransactionManager。 在tomcat下,是没有分布式事务的,不过可以借助于第三方软件jotm(Java Open Transaction Manager )和AtomikosTransactionsEssentials实现,在spring中分布式事务是通过jta(jotm,atomikos)来进行实现。 1、https://www.360docs.net/doc/812877340.html,/ 2、https://www.360docs.net/doc/812877340.html,/Main/TransactionsEssentials 一、使用JOTM例子 (1) Dao及实现 GenericDao接口: ? 1 2 3 4 public interface GenericDao { public int save(String ds, String sql, Object[] obj) throws Exception; public intfindRowCount(String ds, String sql); } GenericDaoImpl实现:? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 public class GenericDaoImpl implements GenericDao{ private JdbcTemplatejdbcTemplateA; private JdbcTemplatejdbcTemplateB; public void setJdbcTemplateA(JdbcTemplatejdbcTemplate) { this.jdbcTemplateA = jdbcTemplate; } public void setJdbcTemplateB(JdbcTemplatejdbcTemplate) { this.jdbcTemplateB = jdbcTemplate; } public int save(String ds, String sql, Object[] obj) throws Exception{ if(null == ds || "".equals(ds)) return -1; try{ if(ds.equals("A")){ return this.jdbcTemplateA.update(sql, obj); }else{ return this.jdbcTemplateB.update(sql, obj); } }catch(Exception e){ e.printStackTrace(); throw new Exception("执行" + ds + "数据库时失败!"); } } public intfindRowCount(String ds, String sql) {

全面分析 Spring 的编程式事务管理及声明式事务管理

开始之前 关于本教程 本教程将深入讲解Spring 简单而强大的事务管理功能,包括编程式事务和声明式事务。通过对本教程的学习,您将能够理解Spring 事务管理的本质,并灵活运用之。 先决条件 本教程假定您已经掌握了Java 基础知识,并对Spring 有一定了解。您还需要具备基本的事务管理的知识,比如:事务的定义,隔离级别的概念,等等。 本文将直接使用这些概念而不做详细解释。另外,您最好掌握数据库的基础知识,虽然这不是必须。 系统需求 要试验这份教程中的工具和示例,硬件配置需求为:至少带有512MB 内存(推荐1GB)的系统。需要安装以下软件: ?Sun JDK 或更新版本或IBM Developer Kit for the Java 5 platform 版本。?Spring framework 。本教程附带的示例代码已经在Spring 上测试过。?MySQL 或更新版本。 ? Spring 事务属性分析 事务管理对于企业应用而言至关重要。它保证了用户的每一次操作都是可靠的,即便出现了异常的访问情况,也不至于破坏后台数据的完整性。就像银行的自助取款机,通常都能正常为客户服务,但是也难免遇到操作过程中机器突然出故障的情况,此时,事务就必须确保出故障前对账户的操作不生效,就像用户刚才完全没有使用过取款机一样,以保证用户和银行的利益都不受损失。 在Spring 中,事务是通过TransactionDefinition 接口来定义的。该接口包含与事务属性有关的方法。具体如清单1所示: 清单1. TransactionDefinition 接口中定义的主要方法 public interface TransactionDefinition{ int getIsolationLevel(); int getPropagationBehavior(); int getTimeout(); boolean isReadOnly();

spring事务传播机制实例讲解

spring事务传播机制实例讲解 Java代码1、 [DEBUG,DataSourceTransactionManager,main] Creating new transaction with name [https://www.360docs.net/doc/812877340.html,erService.addUser]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT 2、[DEBUG,JdbcTemplate,main] Executing SQL statement [insert into t_user(id,name) values(1,'duck')] 3、 [DEBUG,DataSourceTransactionManager,main] Suspending current transaction, creating new transaction with name [com.zx.spring.BookService.addBook] 4、 [DEBUG,JdbcTemplate,main] Executing SQL statement [insert into t_book(id,name) values(1,'duck-j2ee')] 5、[DEBUG,DataSourceTransactionManager,main] Initiating transaction commit 6、 [DEBUG,DataSourceTransactionManager,main] Committing JDBC transaction on Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@1b7ae22] 7、[DEBUG,DataSourceTransactionManager,main] Resuming suspended transaction after completion of inner transaction 8、[DEBUG,DataSourceTransactionManager,main] Initiating transaction commit 9、

spring的@Transactional注解详细用法

spring的@Transactional注解详细用法 各位读友大家好!你有你的木棉,我有我的文章,为了你的木棉,应读我的文章!若为比翼双飞鸟,定是人间有情人!若读此篇优秀文,必成天上比翼鸟! spring的@Transactional注解详细用法Spring Framework对事务管理提供了一致的抽象,其特点如下:为不同的事务API 提供一致的编程模型,比如JTA(Java Transaction API), JDBC, Hibernate, JPA(Java Persistence API和JDO(Java Data Objects)支持声明式事务管理,特别是基于注解的声明式事务管理,简单易用提供比其他事务API如JTA更简单的编程式事务管理API与spring数据访问抽象的完美集成事务管理方式spring支持编程式事务管理和声明式事务管理两种方式。编程式事务管理使用TransactionTemplate或者直接使用底层的PlatformTransactionManager。对于编程式事务管理,spring推荐使用TransactionTemplate。声明式事务管理建立在AOP之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。声明式事务最大的优点就是不需要通过编程的方式管理事务,这样就不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明(或通过基于@Transactional注解的方式),便可以将事务规则应用到业务逻辑中。显然声明式事务管理要优于编程式事务管理,这正是spring

Spring事务配置的五种方式

Spring事务原理 统观spring事务,围绕着两个核心PlatformTransactionManager和TransactionStatus spring提供了几个关于事务处理的类: TransactionDefinition //事务属性定义 TranscationStatus //代表了当前的事务,可以提交,回滚。 PlatformTransactionManager这个是spring提供的用于管理事务的基础接口,其下有一个实现的抽象类AbstractPlatformTransactionManager,我们使用的事务管理类例如DataSourceTransactionManager等都是这个类的子类。 一般事务定义步骤: TransactionDefinition td = new TransactionDefinition(); TransactionStatus ts = transactionManager.getTransaction(td); try { //do sth https://www.360docs.net/doc/812877340.html,mit(ts); } catch(Exception e){transactionManager.rollback(ts);} spring提供的事务管理可以分为两类:编程式的和声明式的。编程式的,比较灵活,但是代码量大,存在重复的代码比较多;声明式的比编程式的更灵活。 编程式主要使用transactionTemplate。省略了部分的提交,回滚,一系列的事务对象定义,需注入事务管理对象. void add() { transactionTemplate.execute( new TransactionCallback(){ pulic Object doInTransaction(TransactionStatus ts) { //do sth} } } 声明式: 使用TransactionProxyFactoryBean: PROPAGATION_REQUIRED PROPAGATION_REQUIRED

计算机软件,spring中事务管理器的配置

浅析Spring提供的事务管理方法

浅析Spring提供的事务管理方法 Spring提供的事务管理可以分为两类:编程式的和声明式的。编程式的,比较灵活,但是代码量大,存在重复的代码比较多;而声明式的比编程式的更灵活方便。本文将讨论这两种事务管理的区别。 传统的JDBC事务管理 以往使用JDBC进行数据操作时,一般采用DataSource,从数据源中得到Connection,我们知道数据源是线程安全的,而连接不是线程安全的,所以对每个请求都是从数据源中重新取出一个连接。一般的数据源由容器进行管理,包括连接池。例如TOMCAT,WEBSPHERE,WEBLOGIC等这些J2EE商业容器都提供了这个功能。 以往的我们使用JDBC在写代码时,事务管理可能会是这样: Connection conn = null; try { conn = DBConnectionFactory.getConnection; conn.setAutoCommit(false); //do something https://www.360docs.net/doc/812877340.html,mit(); //commit transcation } catch(Exception e) { conn.rollback(); //do sth } finally { try { conn.close();

catch(SQLException se){ //do sth.} //close ResultSet,PreparedStatement,Connection //notice:Maybe ocurr Exception when u close rs,pstmt,conn } 按照以往的思路来写代码,代码量比较长,而且容易疏忽,忘掉一些try/catch,引发一些异常无法catch,虽然有时候我们会写DBTool类,来关闭这些资源,并且保证在关闭这些资源时,不向外抛异常。 Spring提供的编程式的事务处理 Spring提供了几个关于事务处理的类: ?TransactionDefinition //事务属性定义 ?TranscationStatus //代表了当前的事务,可以提交,回滚。 ?PlatformTransactionManager这个是spring提供的用于管理事务的基础接口,其下有一个实现的抽象类AbstractPlatformTransactionManager,我们使用的事务管理类例如DataSourceTransactionManager等都是这个类的子类。 我们使用编程式的事务管理流程可能如下: 1 声明数据源 2 声明一个事务管理类,例如DataSourceTransactionManager,HibernateTransactionManger,JTATransactionManager等 3 在我们的代码中加入事务处理代码: TransactionDefinition td = new TransactionDefinition(); TransactionStatus ts = transactionManager.getTransaction(td); try { //do sth https://www.360docs.net/doc/812877340.html,mit(ts); } catch(Exception e){transactionManager.rollback(ts);} 使用spring提供的事务模板TransactionTemplate void add()

在spring中如何配代码的事务管理

在spring中如何配代码的事务管理 在J2EE的web应用里面配置spring非常简单,最简单的只需要把spring得ContextLoaderListener添加到你的web.xml文件里面就可以了,示例如下:org.springframework.web.context.ContextLoaderListener ContextLoaderListener是一个ServletContextListener, 它在你的web应用启动的时候初始化。缺省情况下,它会在WEB-INF/applicationContext.xml文件找Spring的配置。你可以通过定义一个元素名字为”contextConfigLocation”来改变Spring 配置文件的位置。示例 使用”org.springframework.jdbc.datasource.DriverManagerDataSou rce”数据源来配置数据库驱动。示例如下:org.hsqldb.jdbcDriver jdbc:hsqldb:db/appfuse sa spring提供了几个关于事务处理的类:TransactionDefinition //事务属性定义TranscationStatus //代表了当前的事务,可以提交,回滚。PlatformTransactionManager这个是spring提供的用于管理事务的基础接口,其下有一个实现的抽象类AbstractPlatformTransac 在context中定义DataSource,创建SessionFactoy,设置参

数;DAO类继承HibernateDaoSupport,实现具体接口,从中获得HibernateTemplate进行具体操作。在使用中如果遇到OpenSessionInView的问题,可以添加OpenSessionInViewFilter 或OpenSessionInViewIntercepto 一个类需要用到某个接口的方法,我们需要将类A和接口B的实现关联起来,最简单的方法是类A中创建一个对于接口B的实现C 的实例,但这种方法显然两者的依赖(Dependency)太大了。而IoC 的方法是只在类A中定义好用于关联接口B的实现的方法,将类A,接口B和接口B的

spring,mybatis事务管理配置与@Transactional注解使用[转]

spring,mybatis事务管理配置与@Transactional注解使用 [转] spring,mybatis事务管理配置与@Transactional注解使用 概述 事务管理对于企业应用来说是至关重要的,即使出现异常情况,它也可以保证数据的一致性。 Spring Framework对事务管理提供了一致的抽象,其特点如下: 为不同的事务API提供一致的编程模型,比如JTA(Java Transaction API), JDBC, Hibernate, JPA(Java Persistence API和JDO(Java Data Objects)支持声明式事务管理,特别是基于注解的声明式事务管理,简单易用提供比其他事务API如JTA更简单的编程式事务管理API与spring数据访问抽象的完美集成 事务管理方式 spring支持编程式事务管理和声明式事务管理两种方式。 编程式事务管理使用TransactionTemplate或者直接使用底层的PlatformTransactionManager。对于编程式事务管理,spring推荐使用TransactionTemplate。 声明式事务管理建立在AOP之上的。其本质是对方法前后

进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。声明式事务最大的优点就是不需要通过编程的方式管理事务,这样就不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明(或通过基于 @Transactional注解的方式),便可以将事务规则应用到业 务逻辑中。 显然声明式事务管理要优于编程式事务管理,这正是spring 倡导的非侵入式的开发方式。声明式事务管理使业务代码不受污染,一个普通的POJO对象,只要加上注解就可以获得完全的事务支持。和编程式事务相比,声明式事务唯一不足地方是,后者的最细粒度只能作用到方法级别,无法做到像编程式事务那样可以作用到代码块级别。但是即便有这样的需求,也存在很多变通的方法,比如,可以将需要进行事务管理的代码块独立为方法等等。 声明式事务管理也有两种常用的方式,一种是基于tx和aop 名字空间的xml配置文件,另一种就是基于@Transactional 注解。显然基于注解的方式更简单易用,更清爽。 自动提交(AutoCommit)与连接关闭时的是否自动提交 自动提交 默认情况下,数据库处于自动提交模式。每一条语句处于一个单独的事务中,在这条语句执行完毕时,如果执行成功则

spring事务配置详解

Spring事务配置的五种方法 2009-04-24 10:20 总结如下: Spring配置文件中关于事务配置总是由三个组成部分,分别是DataSource、TransactionManager和代理机制这三部分,无论哪种配置方式,一般变化的只是代理机制这部分。 DataSource、TransactionManager这两部分只是会根据数据访问方式有所变化,比如使用Hibernate进行数据访问时,DataSource实际为SessionFactory,TransactionManager的实现为HibernateTransactionManager。 具体如下图: 根据代理机制的不同,总结了五种Spring事务的配置方式,配置文件如下: 第一种方式:每个Bean都有一个代理

spring事务

1.6 Spring事务: 1. 编程式事务管理——编程式的事务管理可以清楚滴控制事务的边界,也就是让您自行实现事务开始时间、撤消操作的时机、结束时间等,可以实现细粒度的事务控制。 2. 声明式事务管理——然而多数的情况下,事务并不需要细粒度的控制,而是采用声明式的事务管理,好处是Spring事务管理的相关API可以不用介入程序之中,从对象的角度来看,它并不知道自己正被纳入事务管理之中,在不需要事务管理的时候,只要在设置文件上修改一下设置,即可移去事务管理服务。 Spring声明式的事务管理依赖它的AOP框架来完成。使用声明式事务管理的好处是,事务管理不能侵入您所开发的组件,具体来说,DAO对象不会意识到正在事务管理之中,事实上也应该如此,因为事务管理是属于系统层面的服务,而不是业务逻辑的一部分,如果想要改变事务管理策略的话,也只需要在定义文件中重新配置。 事务的属性介绍: Spring使用AOP来完成声明式的事务管理,因而声明式事务是以方法为边界的,Spring的事务属性自然就在于描述事务应用至方法上的策略,在Spring 中事务属性分作以下的几个参数:传播行为(Propagation behavior)、隔离层级(Isolation Level)、只读提示(Read-only hints)、事务超时期间(The transaction timeout period) 传播行为(Propagation behavior):传播行为定义了事务应用于方法的边界(Boundaries),它告知何时该开始一个新的事务,或何时事务被暂停,或方法是否要在事务中进行。如,若传播行为设置为PROPAGATION_REQUIRED,则事务的边界在开始第一个事务的方法呼叫及结束时,如果先前没有事务被开始,则事务边界即为目前方法的执行前后。又如果传播行为被声明为PROPAGATION_REQUIRES_NEW,则事务的边界即为该方法执行的前后。 隔离层级(Isolation Level):在一个应用程序中,可能有多个事务同时在进行,这些事务应当彼此之间另一个事务的存在,好比现在整个应用程序就只有一个事务存在,由于事务彼此之间独立,若读取的是同一个数据的话,就容易发生问题。如: 脏读:(Dirty Read)脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另一个事务也访问了这个数据,然后使用了这个数据,由于这个数据是还没有提交的数据,(有可能回滚)那么另外这个事务读到的数据就是脏数据,依据脏数据所做的操作可能是不正确的。 不可重复读:(Non-repeatable read)指在一个事物中,多次读取同一个数据。当这个事务还没结束时,另外一个事务也访问该同一数据。那么,在第一个事务中

Spring 自动事务代理

spring 同时支持编程事务策略和声明式事务策略,大部分时候,都推荐使用声明式事务策略,使用声明式事务策略的优势十分明显。 对于使用声明式事务策略,可以使用TransactionProxyFactoryBean来配置事务代理Bean。正如它的类名所暗示的,它是一个工厂Bean,工厂Bean用于生成一系列的Bean实例,这一系列的Bean实例都是Proxy.这种事务代理正是基于Spring AOP组件。配置TransactionProxyFactoryBean时,一样需要指定目标Bean. 每个TransactionProxyFactoryBean为一个目标Bean生成事务代理,事务代理的方法改写了目标Bean的方法,就是在目标Bean的方法执行之前加入了事务,在目标Bean的方法正常结束之前提交事务,如查遇到了异常则回滚事务。 TransactionProxyFactoryBean创建事务代理时,需要了解当前事务所处的环境,该环境属性通过PlatformTransactionManager实例传入,而相关事务传入规则在TransactionProxyFactoryBean的定义中给出. PROPAGATION_REQUIRED PROPAGATION_REQUIRED PROPAGATION_REQUIRED PROPAGATION_REQUIRED PROPAGATION_REQUIRED PROPAGATION_REQUIRED *0*IF

Spring事务隔离级别

Spring事务隔离级别 本文将介绍Spring事务隔离级别,Spring声明式事务让我们从复杂的事务处理中得到解脱。使得我们再也无需要去处理获得连接、关闭连接、事务提交和回滚等这些操作。 AD: 一、Propagation : key属性确定代理应该给哪个方法增加事务行为。这样的属性最重要的部份是传播行为。 有以下选项可供使用:PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。 PROPAGATION_SUPPORTS 支持当前事务,如果当前没有事务,就以非事务方式执行。 PROPAGATION_MANDATORY 支持当前事务,如果当前没有事务,就抛出异常。 PROPAGATION_REQUIRES_NEW 新建事务,如果当前存在事务,把当前事务挂起。 PROPAGATION_NOT_SUPPORTED 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 PROPAGATION_NEVER 以非事务方式执行,如果当前存在事务,则抛出异常。 1:PROPAGATION_REQUIRED 加入当前正要执行的事务不在另外一个事务里,那么就起一个新的事务

比如说,ServiceB.methodB的事务级别定义为PROPAGATION_REQUIRED, 那么由于执行ServiceA.methodA的时候, ServiceA.methodA已经起了事务,这时调用ServiceB.methodB,ServiceB.methodB看到自己已经运行在ServiceA.methodA 的事务内部,就不再起新的事务。而假如ServiceA.methodA运行的时候发现自己没有在事务中,他就会为自己分配一个事务。 这样,在ServiceA.methodA或者在ServiceB.methodB内的任何地方出现异常,事务都会被回滚。即使ServiceB.methodB的事务已经被提交,但是ServiceA.methodA在接下来fail要回滚,ServiceB.methodB也要回滚。 2:PROPAGATION_SUPPORTS 如果当前在事务中,即以事务的形式运行,如果当前不再一个事务中,那么就以非事务的形式运行。 3:PROPAGATION_MANDATORY 必须在一个事务中运行。也就是说,他只能被一个父事务调用。否则,他就要抛出异常。 4:PROPAGATION_REQUIRES_NEW 这个就比较绕口了。比如我们设计ServiceA.methodA的事务级别为 PROPAGATION_REQUIRED,ServiceB.methodB的事务级别为 PROPAGATION_REQUIRES_NEW,那么当执行到ServiceB.methodB的时候, ServiceA.methodA所在的事务就会挂起,ServiceB.methodB会起一个新的事务,等待ServiceB.methodB的事务完成以后,他才继续执行。他与PROPAGATION_REQUIRED 的事务区别在于事务的回滚程度了。因为ServiceB.methodB是新起一个事务,那么就是存在两个不同的事务。如果ServiceB.methodB已经提交,那么ServiceA.methodA失败回滚,ServiceB.methodB是不会回滚的。如果ServiceB.methodB失败回滚,如果他抛出的异常被ServiceA.methodA捕获,ServiceA.methodA事务仍然可能提交。 5:PROPAGATION_NOT_SUPPORTED

事务管理的五种方法

前段时间对Spring的事务配置做了比较深入的研究,在此之间对Spring的事务配置虽说也配置过,但是一直没有一个清楚的认识。通过这次的学习发觉Spring的事务配置只要把思路理清,还是比较好掌握的。 总结如下: Spring配置文件中关于事务配置总是由三个组成部分,分别是DataSource、TransactionManager和代理机制这三部分,无论哪种配置方式,一般变化的只是代理机制这部分。 DataSource、TransactionManager这两部分只是会根据数据访问方式有所变化,比如使用Hibernate进行数据访问时,DataSource实际为SessionFactory,TransactionManager的实现为HibernateTransactionManager。 具体如下图: 根据代理机制的不同,总结了五种Spring事务的配置方式,配置文件如下:

第一种方式:每个Bean都有一个代理

相关文档
最新文档