本文延续上一文章(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. 重温ASP.NET WebAPI(二)进阶

    重温ASP.NET WebAPI(二)进阶   介绍 本文为个人对WebApi的回顾无参考价值. 本文内容: Rest和UnitOfWork 创建WebAPi的流程 IOC-Unity的使用 MEF ...

  2. php5.4.0以后加入trait实现代码复用【摘录】

    在http://www.php.net/manual/zh/language.oop5.traits.php 查看了一下5.4.0提供的特性trait顺便做一个标记(总结): 首先要明确trait和类 ...

  3. OC-NSArray

    一.认识数组 oc中可以把NSObject对象的子类放到数组这个集合中,但是int.float.double等基础数据类型需要先进行转换才可以存入数组. oc中数组以NS开头,其中分为可变数组和不可变 ...

  4. ADO Recordset 对象链接

    http://baike.baidu.com/link?url=4Xdc46R8M5uj-BbOGaH761N5oDEYlGQJFeR2WbPwx1iQBusAUKU3qbWcHZCMmayatj9n ...

  5. Shell 命令行统计 apache 网站日志访问IP以及IP归属地

    Shell 命令行统计 apache 网站日志访问IP以及IP归属地 我的一个站点用 apache 服务跑着,积攒了很多的日志.我想用 shell 看看有哪些人访问过我的站点,并且他来自哪里. 因为日 ...

  6. fiddler与Charles的区别

    一.Fiddle2(v2.4.2.6,windows) fiddler除了常规的替换http请求.模拟慢网速外,还有一些日常开发里能用到的特殊功能. 1. http代理服务器 fiddler启动的时候 ...

  7. JMter压力测试

    一. 压力测试场景设置 一般我们在做压力测试的时候,分单场景和混合场景,单场景也就是咱们压测单个接口的时候,多场景也就是有业务流程的情况下,比如说一个购物流程,那么这样的场景就是混合场景,就是有多个接 ...

  8. Objective C - 2 - 随机数,可变字符串,字符串,SubString

    int main(int argc, const char * argv[]) { @autoreleasepool { NSString *outputString = @"1234567 ...

  9. go语言】Goroutines 并发模式

    并发模式 让我们先来回顾一下boring函数的例子. func boring(msg string, c chan string) {    for i := 0; ; i++ {         c ...

  10. U-Boot 不能识别FAT32 SD分区

    /********************************************************************* * U-Boot 不能识别FAT32 SD分区 * 说明: ...