本文延续上一文章(spring事务传播特性实验(1):数据准备),在已经准备好环境的情况下,做如下的实验,以验证spring传播特性,加深对spring传播特性的理解。

  本次主要验证PROPAGATION_REQUIRED的传播特性:

  TransactionDefinition.PROPAGATION_REQUIRED

  TransactionDefinition.PROPAGATION_REQUIRED:根据spring的定义PROPAGATION_REQUIRED即需要事务的支持,如果没有的情况下会自己创建一个新的事务

  我们进行如下测试:

  A、外部有事务的情况下:http://localhost:8080/test1?type=0

DEBUG  137  DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Acquired Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@1512c465] for JDBC transaction
DEBUG 143 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Switching JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@1512c465] to manual commit
INFO 149 INFO com.sapling.project.module.biz.TransactionTest - [outerTransaction]current transaction name : outerTransaction
INFO 151 INFO com.sapling.project.module.biz.TransactionTest - {name:0}
DEBUG 263 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Participating in existing transaction
INFO 263 INFO com.sapling.project.module.biz.TransactionTest - [doInnerTransaction 0 ]current transaction name : outerTransaction
INFO 263 INFO com.sapling.project.module.biz.TransactionTest - {name:0}
INFO 267 INFO com.sapling.project.module.biz.TransactionTest - [doInnerTransaction]current transaction outerTransaction commit.
DEBUG 268 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Initiating transaction commit
DEBUG 268 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Committing JDBC transaction on Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@1512c465]
DEBUG 274 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Releasing JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@1512c465] after transaction
DEBUG 274 DEBUG o.springframework.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource
INFO 275 INFO com.sapling.project.module.biz.TransactionTest - [outerTransaction]current transaction null commit.

  从日志中我们可以看到这样的记录:Participating in existing transaction,加入到一个已经存在的事务中。

  数据表插入成功

+----+----------+------+--------+
| id | name | sex | status |
+----+----------+------+--------+
| 8 | 0-true | NULL | NULL |
| 9 | i-0-true | NULL | NULL |

  B、外部没有事务的情况下:http://localhost:8080/test3?type=0

 INFO 093 INFO  com.sapling.project.module.biz.TransactionTest - [outerTransaction] did not have transaction
INFO 094 INFO com.sapling.project.module.biz.TransactionTest - {name:0}
DEBUG 094 DEBUG o.springframework.jdbc.datasource.DataSourceUtils - Fetching JDBC Connection from DataSource
DEBUG 104 DEBUG o.springframework.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource
DEBUG 104 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Creating new transaction with name [null]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
DEBUG 104 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Acquired Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@1512c465] for JDBC transaction
DEBUG 104 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Switching JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@1512c465] to manual commit
INFO 106 INFO com.sapling.project.module.biz.TransactionTest - [doInnerTransaction 0 ]current transaction name : null
INFO 107 INFO com.sapling.project.module.biz.TransactionTest - {name:0}
DEBUG 111 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Initiating transaction commit
DEBUG 111 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Committing JDBC transaction on Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@1512c465]
DEBUG 118 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Releasing JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@1512c465] after transaction
DEBUG 119 DEBUG o.springframework.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource
INFO 119 INFO com.sapling.project.module.biz.TransactionTest - [doInnerTransaction]current transaction null commit.

   Creating new transaction with name [null]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,创建一个新的事务,传播特性为PROPAGATION_REQUIRED,隔离级别为默认。

  数据表插入成功

mysql> select * from sys_user
-> ;
+----+----------+------+--------+
| id | name | sex | status |
+----+----------+------+--------+
| 8 | 0-true | NULL | NULL |
| 9 | i-0-true | NULL | NULL |
| 10 | o-0-true | NULL | NULL |
| 11 | i-0-true | NULL | NULL |
+----+----------+------+--------+
4 rows in set (0.00 sec)

  C、外部有事务,但内部异常的情况下:

  系统报500错误,日志如下:

165 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Creating new transaction with name [null]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
172 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Acquired Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@5d7163af] for JDBC transaction
172 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Switching JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@5d7163af] to manual commit
174 INFO com.sapling.project.module.biz.TransactionTest - [outerTransaction]current transaction name : outerTransaction
174 INFO com.sapling.project.module.biz.TransactionTest - {name:o-0-true}
178 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Participating in existing transaction
178 INFO com.sapling.project.module.biz.TransactionTest - [doInnerTransaction 0 ]current transaction name : outerTransaction
178 INFO com.sapling.project.module.biz.TransactionTest - {name:11111111111111111111111111111}
284 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Participating transaction failed - marking existing transaction as rollback-only
284 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Setting JDBC transaction [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@5d7163af] rollback-only
284 INFO com.sapling.project.module.biz.TransactionTest - [doInnerTransaction ]current transaction outerTransaction rollback. 284 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Global transaction is marked as rollback-only but transactional code requested commit 284 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Initiating transaction rollback 284 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Rolling back JDBC transaction on Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@5d7163af] 319 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Releasing JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@5d7163af] after transaction 319 DEBUG o.springframework.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource 326 DEBUG org.springframework.web.servlet.DispatcherServlet - Could not complete request org.springframework.transaction.IllegalTransactionStateException: Transaction is already completed - do not call commit or rollback more than once per transaction

  可以看到,事务在在内部方法中就直接回滚了,整个事务已经完成了,外部事务再在做回滚操作的时候,就报错了,这里可以在回滚操作之前加上!status.isCompleted()检查事务是不是完成了,完成了则不需要再回滚了。

  检查数据库,可以看出事务整个失败了,不管是内部方法还是外部方法的数据都没有插入成功:

mysql> select * from sys_user;
+----+----------+------+--------+
| id | name | sex | status |
+----+----------+------+--------+
| 8 | 0-true | NULL | NULL |
| 9 | i-0-true | NULL | NULL |
| 10 | o-0-true | NULL | NULL |
| 11 | i-0-true | NULL | NULL |
+----+----------+------+--------+
4 rows in set (0.00 sec)

  D、外部没有事务,内部执行失败:

.964 INFO  com.sapling.project.module.biz.TransactionTest - [outerTransaction] did not have transaction
.964 INFO com.sapling.project.module.biz.TransactionTest - {name:0-true}
.964 DEBUG o.springframework.jdbc.datasource.DataSourceUtils - Fetching JDBC Connection from DataSource
.973 DEBUG o.springframework.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource
.973 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Creating new transaction with name [null]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
.973 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Acquired Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@5b773cec] for JDBC transaction
.973 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Switching JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@5b773cec] to manual commit
.974 INFO com.sapling.project.module.biz.TransactionTest - [doInnerTransaction 0 ]current transaction name : null
.974 INFO com.sapling.project.module.biz.TransactionTest - {name:11111111111111111111111111111}
.978 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Initiating transaction rollback
.978 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Rolling back JDBC transaction on Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@5b773cec]
.982 DEBUG o.s.jdbc.datasource.DataSourceTransactionManager - Releasing JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@5b773cec] after transaction
.982 DEBUG o.springframework.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource
.982 INFO com.sapling.project.module.biz.TransactionTest - [doInnerTransaction ]current transaction null rollback.

  

  数据库表查询结果:

mysql> select * from sys_user;
+----+----------+------+--------+
| id | name | sex | status |
+----+----------+------+--------+
| 8 | 0-true | NULL | NULL |
| 9 | i-0-true | NULL | NULL |
| 10 | o-0-true | NULL | NULL |
| 11 | i-0-true | NULL | NULL |
| 16 | 0-true | NULL | NULL |
+----+----------+------+--------+
5 rows in set (0.00 sec)

  可以看出来,内部事务的失败不同事务下的插入操作。

由如上的几个执行结果可以看出来,Required传播模式下的事务,会在已经存在事务的情况下加入已有的事务,按照现有事务的流程执行,没有事务的情况下,新建一个事务执行,其执行的结果对其他的事务不产生影响。

spring事务传播特性实验(2):PROPAGATION_REQUIRED实验结果与分析的更多相关文章

  1. 事务、事务特性、事务隔离级别、spring事务传播特性

    事务.事务特性.事务隔离级别.spring事务传播特性   1.什么是事务: 事务是程序中一系列严密的操作,所有操作执行必须成功完成,否则在每个操作所做的更改将会被撤销,这也是事务的原子性(要么成功, ...

  2. 什么是事务、事务特性、事务隔离级别、spring事务传播特性

    1.什么是事务: 事务是程序中一系列严密的操作,所有操作执行必须成功完成,否则在每个操作所做的更改将会被撤销,这也是事务的原子性(要么成功,要么失败). 2.事务特性: 事务特性分为四个:原子性(At ...

  3. Spring事务传播特性的浅析——事务方法嵌套调用的迷茫

    Spring事务传播机制回顾 Spring事务一个被讹传很广说法是:一个事务方法不应该调用另一个事务方法,否则将产生两个事务.结果造成开发人员在设计事务方法时束手束脚,生怕一不小心就踩到地雷. 其实这 ...

  4. 什么是事务?事务特性?事务隔离级别?spring事务传播特性?

    一.事务的概述 什么是事务? 在数据库中,所谓事务是指一组逻辑操作单元即一组sql语句,当这个单元中的一部分操作失败,整个事务回滚,只有全部正确才完成提交.判断事务是否配置成功的关键点在于出现异常时事 ...

  5. 解惑spring事务传播特性之嵌套事务

    /** * Support a current transaction, create a new one if none exists. * Analogous to EJB transaction ...

  6. spring 事务传播特性 和隔离级别

    事务的几种传播特性1. PROPAGATION_REQUIRED: 如果存在一个事务,则支持当前事务.如果没有事务则开启2. PROPAGATION_SUPPORTS: 如果存在一个事务,支持当前事务 ...

  7. Spring 事务传播特性

    Spring 事务属性一共有四种:传播行为.隔离级别.只读和事务超时 a)   传播行为定义了被调用方法的事务边界. 传播行为 意义 PROPERGATION_MANDATORY 表示方法必须运行在一 ...

  8. 数据库与spring事务传播特性

    一.spring事务管理的实现原理,基于AOP 1) REQUIRED ,这个是默认的属性 Support a current transaction, create a new one if non ...

  9. Spring 事务传播行为实验

    一.Propagation : key属性确定代理应该给哪个方法增加事务行为.这样的属性最重要的部份是传播行为.有以下选项可供使用: PROPAGATION_REQUIRED--支持当前事务,如果当前 ...

随机推荐

  1. hdu 6092 Rikka with Subset(逆向01背包+思维)

    Rikka with Subset Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others ...

  2. PostgreSQL文档编译

    之前一直没有将doc进行编译,最近编译成功了,却无法用man来查看,发现是没有将man的目录添加到搜索路径: MANPATH /usr/pgsql-10/share/man 加入到 /etc/man. ...

  3. PostgreSQL统计信息挖掘

    PG提供了丰富的统计信息,但是没有将这些统计信息使用的简单查询搞成存储过程,需要我们自己根据需要灵活的去挖掘,最近做了数据库监控,用了一些简单的东西,于是想往深了挖一下. 首先看看系统表和视图,他们都 ...

  4. Iphone 消息通知(APNS)的3种方式 -- C# 和 nodejs

    发送 APNS 使用 p12 文件(C#) public static bool PushWithP12(string apnToken, string message) { _log.DebugFo ...

  5. D. Closest Equals(线段树)

    题目链接: D. Closest Equals time limit per test 3 seconds memory limit per test 256 megabytes input stan ...

  6. Linux 大文件的分割与合并

    1.分割 -- split命令 可以指定按行数分割和按字节大小分割两种模式. (1) 按行数分割 $ large_file.txt new_file_prefix 加上-d,使用数字后缀:加上--ve ...

  7. css3公共样式

    温馨提示:一下css封装,建议按需使用,否则会造成很大的代码冗余,且很多样式会造成不符合预期的效果,建议合理使用 <a href="https://meyerweb.com/eric/ ...

  8. AX内部公司

    <object width="450" height="500" align="middle" id="reader&quo ...

  9. Java并发--synchronized

    以下是本文的目录大纲: 一.什么时候会出现线程安全问题? 二.如何解决线程安全问题? 三.synchronized同步方法或者同步块 转载原文链接:http://www.cnblogs.com/dol ...

  10. JSP学习(四)JSP属性范围

    P属性范围 四种属性范围分别指以下四种: 当前页page:一个属性只能在一个页面中取得,跳转到其他页面无法取得 一次服务器请求request:一个页面中设置的属性,只要经过了服务器跳转,则跳转之后的页 ...