Spring事务传播机制和数据库隔离级别

转载 2010年06月26日 10:52:00

先看下Spring的 事务传播行为类型

事务传播行为类型

说明

PROPAGATION_REQUIRED

如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是 最常见的选择。

PROPAGATION_SUPPORTS

支持当前事务,如果当前没有事务,就以非事务方式执行。

PROPAGATION_MANDATORY

使用当前的事务,如果当前没有事务,就抛出异常。

PROPAGATION_REQUIRES_NEW

新建事务,如果当前存在事务,把当前事务挂起。

PROPAGATION_NOT_SUPPORTED

以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

PROPAGATION_NEVER

以非事务方式执行,如果当前存在事务,则抛出异常。

PROPAGATION_NESTED

如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与 PROPAGATION_REQUIRED 类似的操作。

当使用 PROPAGATION_NESTED 时, 底层的数据源必须基于 JDBC 3.0 ,并且实现者需要支持保存点事务机制。

readOnly 
      事务属性中的readOnly标志表示对应的事务应该被最优化为只读事务。这 是一个最优化提示 。在一些情况下,一些事务策略能够起到显著的最优化效果,例如在使用Object/Relational映射工具 (如:Hibernate或TopLink)时避免dirty checking(试图“刷新”)。

Timeout
       在事务属性中还有定义“timeout”值的选项,指定事务超时为几秒。在JTA中,这将被简单地传递到J2EE服务器的事务协调程序,并据此得到相应的 解释。
在xml中的设置应该是 timeout_11 表示超时为11秒。。
为什么呢。。看下面的源码可知。。
  1. /**
  2. * PropertyEditor for TransactionAttribute objects. Takes Strings of form
  3. * <p><code>PROPAGATION_NAME,ISOLATION_NAME,readOnly,timeout_NNNN,+Exception1,-Exception2</code>
  4. * <p>where only propagation code is required. For example:
  5. * <p><code>PROPAGATION_MANDATORY,ISOLATION_DEFAULT</code>
  6. *
  7. * <p>The tokens can be in <strong>any</strong> order. Propagation and isolation codes
  8. * must use the names of the constants in the TransactionDefinition class. Timeout values
  9. * are in seconds. If no timeout is specified, the transaction manager will apply a default
  10. * timeout specific to the particular transaction manager.
  11. *
  12. * <p>A "+" before an exception name substring indicates that
  13. * transactions should commit even if this exception is thrown;
  14. * a "-" that they should roll back.
  15. *
  16. * @author Rod Johnson
  17. * @author Juergen Hoeller
  18. * @since 24.04.2003
  19. * @see org.springframework.transaction.TransactionDefinition
  20. * @see org.springframework.core.Constants
  21. */
  22. public class TransactionAttributeEditor extends PropertyEditorSupport {
  23. /**
  24. * Format is PROPAGATION_NAME,ISOLATION_NAME,readOnly,timeout_NNNN,+Exception1,-Exception2.
  25. * Null or the empty string means that the method is non transactional.
  26. * @see java.beans.PropertyEditor#setAsText(java.lang.String)
  27. */
  28. public void setAsText(String s) throws IllegalArgumentException {
  29. if (s == null || "".equals(s)) {
  30. setValue(null);
  31. }
  32. else {
  33. // tokenize it with ","
  34. String[] tokens = StringUtils.commaDelimitedListToStringArray(s);
  35. RuleBasedTransactionAttribute attr = new RuleBasedTransactionAttribute();
  36. for (int i = 0; i < tokens.length; i++) {
  37. String token = tokens[i].trim();
  38. if (token.startsWith(RuleBasedTransactionAttribute.PREFIX_PROPAGATION)) {
  39. attr.setPropagationBehaviorName(token);
  40. }
  41. else if (token.startsWith(RuleBasedTransactionAttribute.PREFIX_ISOLATION)) {
  42. attr.setIsolationLevelName(token);
  43. }
  44. else if (token.startsWith(RuleBasedTransactionAttribute.PREFIX_TIMEOUT)) {
  45. String value = token.substring(DefaultTransactionAttribute.PREFIX_TIMEOUT.length());
  46. attr.setTimeout(Integer.parseInt(value));
  47. }
  48. else if (token.equals(RuleBasedTransactionAttribute.READ_ONLY_MARKER)) {
  49. attr.setReadOnly(true);
  50. }
  51. else if (token.startsWith(RuleBasedTransactionAttribute.PREFIX_COMMIT_RULE)) {
  52. attr.getRollbackRules().add(new NoRollbackRuleAttribute(token.substring(1)));
  53. }
  54. else if (token.startsWith(RuleBasedTransactionAttribute.PREFIX_ROLLBACK_RULE)) {
  55. attr.getRollbackRules().add(new RollbackRuleAttribute(token.substring(1)));
  56. }
  57. else {
  58. throw new IllegalArgumentException("Illegal transaction attribute token: [" + token + "]");
  59. }
  60. }
  61. setValue(attr);
  62. }
  63. }
  64. }
从上面可以看出  token.substring() 这个方法把前缀timeout_给去掉了。。所以只剩下11了
从源码可看出来,PREFIX_XXXX  大都是这样写的,但前缀却是写在后面的。。觉得是不是命名有点古怪了,应该是XXXX_PREFIX,害我分析了一段时间。不过在源码上面的解释倒很清 楚:
 * PropertyEditor for TransactionAttribute objects. Takes Strings of form
 * <p><code>PROPAGATION_NAME,ISOLATION_NAME,readOnly,timeout_NNNN,+Exception1,-Exception2</code>
 * <p>where only propagation code is required. For example:
 * <p><code>PROPAGATION_MANDATORY,ISOLATION_DEFAULT</code>
文笔不好。。就给出个实例,我想一看就该明白了。
  1. <bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
  2. <!--  事务拦截器bean需要依赖注入一个事务管理器 -->
  3. <property name="transactionManager" ref="transactionManager"/>
  4. <property name="transactionAttributes">
  5. <!--  下面定义事务传播属性-->
  6. <props>
  7. <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
  8. <prop key="*">PROPAGATION_REQUIRED,timeout_11</prop>
  9. </props>
  10. </property>
  11. </bean>
总结先到这里。。等深入研究的时候再把写详细些。。。
 
 
事务隔离级别
 
 
      数据库并发操作存在的异常情况:
1. 更新丢失(Lost update): 两个事务都同时更新一行数据但是第二个事务却中途失败退出导致对数据两个修改都失效了这是系统没有执 行任何锁操作因此并发事务并没有被隔离开来。
2. 脏读取(Dirty Reads): 一个事务开始读取 了某行数据但是另外一个事务已经更新了此数据但没有能够及时提交。这是相当危险很可能所有操作都被回滚。
3. 不可重复读取(Non-repeatable Reads): 一 个事务对同一行数据重复读取两次但是却得到了不同结果。例如在两次读取中途有另外一个事务对该行数据进行了修改并提交。
4. 两次更新问题(Second lost updates problem): 无法重复读取特例,有两个并发事务同时读取同一行数据然后其中一个对它进行修改提交而另一个也进行了修改提交这就会造成 第一次写操作失效。
5. 幻读(Phantom Reads): 也称为幻像(幻 影)。事务在操作过程中进行两次查询,第二次查询结果包含了第一次查询中未出现的数据(这里并不要求两次查询SQL语句相同)这是因为在两次查询过程中有 另外一个事务插入数据造成的。
      为了避免上面出现几种情况在标准SQL规范中定义了4个事务隔离级别,不同隔离级别对事务处理不同 。
1.未授权读取(Read Uncommitted): 也称 未提交读。允许脏读取但不允许更新丢失,如果一个事务已经开始写数据则另外一个数据则不允许同时进行写操作但允许其他事务读此行数据。该隔离级别可以通过 “排他写锁”实现。事务隔离的最低级别,仅可保证不读取物理损坏的数据。与READ COMMITTED 隔离级相反,它允许读取已经被其它用户修改但尚未提交确定的数据。
2. 授权读取(Read Committed): 也称提交 读。允许不可重复读取但不允许脏读取。这可以通过“瞬间共享读锁”和“排他写锁”实现,读取数据的事务允许其他事务继续访问该行数据,但是未提交写事务将 会禁止其他事务访问该行。SQL Server 默认的级别。在此隔离级下,SELECT 命令不会返回尚未提交(Committed) 的数据,也不能返回脏数据。
3. 可重复读取(Repeatable Read): 禁止 不可重复读取和脏读取。但是有时可能出现幻影数据,这可以通过“共享读锁”和“排他写锁”实现,读取数据事务将会禁止写事务(但允许读事务),写事务则禁 止任何其他事务。在此隔离级下,用SELECT 命令读取的数据在整个命令执行过程中不会被更改。此选项会影响系统的效能,非必要情况最好不用此隔离级。
4. 串行(Serializable): 也称可串行读。提 供严格的事务隔离,它要求事务序列化执行,事务只能一个接着一个地执行,但不能并发执行。如果仅仅通过“行级锁”是无法实现事务序列化的,必须通过其他机 制保证新插入的数据不会被刚执行查询操作事务访问到。事务隔离的最高级别,事务之间完全隔离。如果事务在可串行读隔离级别上运行,则可以保证任何并发重叠 事务均是串行的。

隔离级别     更新丢失 脏读取 重复读取 幻读 
未授权读取     N            Y         Y          Y 
授权读取        N            N         Y          Y 
可重复 读取     N            N         N         Y 
串行               N            N         N         N

Spring事务传播机制和数据库隔离级别的更多相关文章

  1. 理解 spring 事务传播行为与数据隔离级别

    事务,是为了保障逻辑处理的原子性.一致性.隔离性.永久性. 通过事务控制,可以避免因为逻辑处理失败而导致产生脏数据等等一系列的问题. 事务有两个重要特性: 事务的传播行为 数据隔离级别 1.事务传播行 ...

  2. Spring 事务传播机制和数据库的事务隔离级别

    Propagation(事务传播属性) 类别 传播类型 说明 支持当前事务 REQUIRED 如果当前没有事务,就新建一个事务.@Transaction的默认选择 支持当前事务 SUPPORTS 就以 ...

  3. Spring事务传播机制与隔离级别(转)

    Spring事务传播机制与隔离级别 博客分类: Spring   转自:http://blog.csdn.net/edward0830ly/article/details/7569954 (写的不错) ...

  4. spring事务传播机制实例讲解

    http://kingj.iteye.com/blog/1680350   spring事务传播机制实例讲解 博客分类:   spring java历险     天温习spring的事务处理机制,总结 ...

  5. 面试突击87:说一下 Spring 事务传播机制?

    Spring 事务传播机制是指,包含多个事务的方法在相互调用时,事务是如何在这些方法间传播的. 既然是"事务传播",所以事务的数量应该在两个或两个以上,Spring 事务传播机制的 ...

  6. spring 事务传播机制

    spring 事务 传播机制 描述的 事务方法直接相互调用,父子事物开启,挂起,回滚 等的处理方式. 绿色的 那几个 我认为比较重要. 1 , @Transactional(propagation=P ...

  7. 数据库事务的四大特性以及事务的隔离级别-与-Spring事务传播机制&隔离级别

    数据库事务的四大特性以及事务的隔离级别   本篇讲诉数据库中事务的四大特性(ACID),并且将会详细地说明事务的隔离级别. 如果一个数据库声称支持事务的操作,那么该数据库必须要具备以下四个特性: ⑴ ...

  8. spring事务传播机制的测试结果

    /**     * @Component是个一般性的注解,使用此注解修饰的POJO类,有value属性,指定bean的id.也可不写.默认值是类名首字母小写     * @Resource是控制依赖注 ...

  9. Spring事务传播机制

    Spring在TransactionDefinition接口中规定了7种类型的事务传播行为,它们规定了事务方法和事务方法发生嵌套调用时事务如何进行传播,即协调已经有事务标识的方法之间的发生调用时的事务 ...

随机推荐

  1. UVA1601 状态搜索

    很有意思的一道题,就是迷宫问题的增强版.但是细节很多,有一个技巧就是把每个可以走的位置编号方便状态判重. AC代码: #include<cstdio> #include<cstrin ...

  2. SELinux一键开启与禁用脚本

    SELinux是美国国家安全局(NSA)对于强制访问控制的实现,是 Linux历史上最杰出的新安全子系统.但是SELinux的并不能与众多服务很好的兼容,有些人会关闭SELinux一了百了.在日常的运 ...

  3. jstree树形菜单

    final 用于声明属性.方法和类,分别表示属性不可变,方法不可重写,类不可继承.其实可以参考用easyui的tree 和 ztree参考: https://www.jstree.com/demo/ ...

  4. CSS盒模型的深度思考及BFC

    本文最初发表于博客园,并在GitHub上持续更新前端的系列文章.欢迎在GitHub上关注我,一起入门和进阶前端. 以下是正文. 题目:谈一谈你对CSS盒模型的认识 专业的面试,一定会问 CSS 盒模型 ...

  5. 终于,我也要出一本C#的书了 - 我的写作历程与C#书单推荐

    我之前的面试题停了很久,是因为 - 我写书去了. 前言 我于2012年3月开始工作,到现在马上就满六年了.这六年里,我从一个连Sql server是什么都不知道,只会写最简单的c#的程序员开始做起,一 ...

  6. 【Unity3D】Unity3D开发《我的世界》之四、创建一个Block

    转载请注明出处:http://www.cnblogs.com/shamoyuu/p/unity_minecraft_04.html 一.新建Block类 我们的Block类用来存储跟Block相关的信 ...

  7. RMAN还原时注意set newname时文件名不要有空格

      今天遇到一个非常奇怪的现象,查看ORACLE数据库的一个文件,明明这个文件是存在的,但是使用ls -lrt 查看都显示这个文件不存在.很是纳闷! 后面发现在终端输入文件名后并使用tab键时,发现文 ...

  8. dojo中表格行隐藏出错

    1.错误描述 TypeError:role._by_idx[e.rowIndex].hide is not a function           (54 out of range 3) 2.错误原 ...

  9. Android的sdk、api及工程目录说明

    SDK下包的说明1:add-ons:Android开发需要的第三方文件和软件库2:docs:Android的文档.包括开发指南.API参考.资源等3:extras:扩展的附加包4:platforms: ...

  10. TortoiseSVN设置忽略文件和目录文件夹

    TortoiseSVN设置忽略文件和目录文件夹  在多数项目中你总会有文件和目录不需要进行版本控制.这可能包括一些由编译器生成的文件,*.obj,*.lst,或许是一个用于存放可执行程序的输出文件夹. ...