现在的位置: 首页 > 综合 > 正文

事务管理

2013年06月23日 ⁄ 综合 ⁄ 共 2671字 ⁄ 字号 评论关闭

 结合Spring的事务配置,描述jdbc的事务

 

参考文档:

1、http://www.javaeye.com/topic/78674

2、http://www.javaeye.com/topic/35907

 

使用Spring声明式事务时,有一个非常重要的概念就是事务属性。事务属性通常由事务的传播行为,事务的隔离级别,事务的超时值和事务只读标志组成。我们在进行事务划分时,需要进行事务定义,也就是配置事务的属性。
Spring在TransactionDefinition接口中定义这些属性,以供PlatfromTransactionManager使用, PlatfromTransactionManager是spring事务管理的核心接口。

 

  getTimeout()方法:它返回事务必须在多少秒内完成。
isReadOnly()方法:事务是否只读,事务管理器能够根据这个返回值进行优化,确保事务是只读的。
getIsolationLevel()方法:返回事务的隔离级别,事务管理器根据它来控制另外一个事务可以看到本事务内的哪些数据。

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

 

 

在TransactionDefinition接口中定义了五个不同的事务隔离级别。
ISOLATION_DEFAULT 这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别.另外四个与JDBC的隔离级别相对应;
ISOLATION_READ_UNCOMMITTED 这是事务最低的隔离级别,它充许别外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻像读;
ISOLATION_READ_COMMITTED 保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据。这种事务隔离级别可以避免脏读出现,但是可能会出现不可重复读和幻像读;
ISOLATION_REPEATABLE_READ 这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免在一个事务中前后两次读取的结果不一致的情况产生(不可重复读);
ISOLATION_SERIALIZABLE 这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。除了防止脏读,不可重复读外,还避免了幻像读。

脏读是读取了未提交的数据(数据不一定被提交),不可重复读是读取了提交事务前后的数据(数据值不一致),幻像读是读取了新增数据事务前后的数据(数据行不一致)。

 

 

在TransactionDefinition接口中定义了七个事务传播行为。
PROPAGATION_REQUIRED  如果存在一个事务,则支持当前事务。如果没有事务则开启一个新的事务;
PROPAGATION_SUPPORTS  如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行。但是对于事务同步的事务管理器,PROPAGATION_SUPPORTS与不使用事务有少许不同;
PROPAGATION_MANDATORY  如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常;
PROPAGATION_REQUIRES_NEW  总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起;
PROPAGATION_NOT_SUPPORTED  总是非事务地执行,并挂起任何存在的事务;
PROPAGATION_NEVER  总是非事务地执行,如果存在一个活动事务,则抛出异常;
PROPAGATION_NESTED  如果一个活动的事务存在,则运行在一个嵌套的事务中. 如果没有活动事务, 则按TransactionDefinition.PROPAGATION_REQUIRED 属性执行;
 
嵌套事务,使用JDBC 3.0驱动时,仅仅支持DataSourceTransactionManager作为事务管理器。需要JDBC 驱动的java.sql.Savepoint类。有一些JTA的事务管理器实现可能也提供了同样的功能。
使用PROPAGATION_NESTED,还需要把PlatformTransactionManager的nestedTransactionAllowed属性设为true; 而nestedTransactionAllowed属性值默认为false;
嵌套事务一个非常重要的概念就是内层事务依赖于外层事务。外层事务失败时,会回滚内层事务所做的动作。而内层事务操作失败并不会引起外层事务的回滚。

 

PROPAGATION_NESTED 与PROPAGATION_REQUIRES_NEW的区别:
它们非常类似,都像一个嵌套事务,如果不存在一个活动的事务,都会开启一个新的事务。使用PROPAGATION_REQUIRES_NEW时,内层事务与外层事务就像两个独立的事务一样,一旦内层事务进行了提交后,外层事务不能对其进行回滚。两个事务互不影响。两个事务不是一个真正的嵌套事务。同时它需要JTA事务管理器的支持。
使用PROPAGATION_NESTED时,外层事务的回滚可以引起内层事务的回滚。而内层事务的异常并不会导致外层事务的回滚,它是一个真正的嵌套事务。DataSourceTransactionManager使用savepoint支持PROPAGATION_NESTED时,需要JDBC 3.0以上驱动及1.4以上的JDK版本支持。其它的JTA TrasactionManager实现可能有不同的支持方式。
JDBC3.0以上时,PROPAGATION_NESTED 开始一个 "嵌套的" 事务时,  它是已经存在事务(外部事务)的一个真正的子事务. 潜套事务开始执行时,  它将取得一个外部事务的 savepoint. 如果这个嵌套事务失败, 我们将回滚到此 savepoint. 潜套事务是外部事务的一部分, 只有外部事务结束后它才会被提交,外部事务回滚时将被一起回滚掉。

 

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

 

抱歉!评论已关闭.