所谓事务传播行为就是多个事务方法相互调用时,事务如何在这些方法间传播。Spring 支持 7 种事务传播行为:

  • PROPAGATION_REQUIRED 如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。
  • PROPAGATION_SUPPORTS 支持当前事务,如果当前没有事务,就以非事务方式执行。
  • PROPAGATION_MANDATORY 使用当前的事务,如果当前没有事务,就抛出异常。
  • PROPAGATION_REQUIRES_NEW 新建事务,如果当前存在事务,把当前事务挂起。
  • PROPAGATION_NOT_SUPPORTED 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
  • PROPAGATION_NEVER 以非事务方式执行,如果当前存在事务,则抛出异常。
  • PROPAGATION_NESTED 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与 PROPAGATION_REQUIRED 类似的操作。

Spring 默认的事务传播行为是 PROPAGATION_REQUIRED,它适合于绝大多数的情况。假设 ServiveX#methodX() 都工作在事务环境下(即都被 Spring 事务增强了),假设程序中存在如下的调用 链:Service1#method1()->Service2#method2()->Service3#method3(),那么这 3 个服务类的 3 个方法通过 Spring 的事务传播机制都工作在同一个事务中。

spring 管理事务一般配置在service层、曾经用struts把事务配置在action层 导致系统并发卡死特别严重 分析了下原因:action层并发量过大、数据库经常锁死在某一块;

spring 配置在service层研究:

测试方法:查询---》更新-----》查询   分析数据在什么时候提交至数据库

一  在同一个service中 互相调本类中的方法

@Service
@Transactional(propagation = Propagation.REQUIRED,rollbackFor={RuntimeException.class, Exception.class})  // 当标于类前时, 标示类中所有方法都进行事物处理
public class LoginService extends BaseServiceImpl implements ILoginService {

@Autowired
    private ILoginDao loginDao;

@Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public ResultBase login(SysUser sysUser) {
        ResultBase res=new ResultBase();
        SysUser user=(SysUser) loginDao.get(SysUser.class,sysUser.getUuid());
        res.setObj(user);
        res.setResult(ResultBase.RESULT_SUCC);
        res.setMessage("成功");
        return res;
    }
    @Transactional(propagation = Propagation.REQUIRED)
    public ResultBase update(SysUser sysUser) {
        ResultBase res=new ResultBase();
        loginDao.update(sysUser);
        res.setResult(ResultBase.RESULT_SUCC);
        res.setMessage("成功");
        return res;
    }
    @Transactional(propagation = Propagation.SUPPORTS)  //此方法用于测试 结果 数据库中在此方法走完才更新至数据库
    public ResultBase searchAndUpdate(SysUser sysUser) {
        ResultBase res=new ResultBase();
        res=login(sysUser);
        sysUser=(SysUser) res.getObj();
        sysUser.setLoginname("123");
        update(sysUser);
        res.setMessage("成功");
        return res;
    }

二  在不同service中 互相调别的service中的方法:第一层事务传播使用NOT_SUPPORTED

@Service
@Transactional(propagation = Propagation.REQUIRED,rollbackFor={RuntimeException.class, Exception.class})  // 当标于类前时, 标示类中所有方法都进行事物处理
public class OperateService extends BaseServiceImpl implements IOperateService {

@Autowired
    private ILoginService loginService;
    
    /**
     * 事务测试:一个service 调另一个 service 何时更新数据
     * @param sysUser
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public ResultBase TransactionTset(SysUser sysUser) {
        ResultBase res=new ResultBase();
        res=loginService.login(sysUser);
        sysUser=(SysUser) res.getObj();
        sysUser.setLoginname("123");
        loginService.update(sysUser);
        res=loginService.login(sysUser);
        res.setMessage("成功");
        return res;
    }

结果:方法执行完    loginService.update(sysUser);后数据已经提交  注意:TransactionTset方法@Transactional(propagation = Propagation.NOT_SUPPORTED)设置不使用事务

三  在不同service中 互相调别的service中的方法:第一层事务传播使用REQUIRED

@Service
@Transactional(propagation
= Propagation.REQUIRED,rollbackFor={RuntimeException.class,
Exception.class})  // 当标于类前时, 标示类中所有方法都进行事物处理
public class OperateService extends BaseServiceImpl implements IOperateService {

@Autowired
    private ILoginService loginService;
    
    /**
     * 事务测试:一个service 调另一个 service 何时更新数据
     * @param sysUser
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public ResultBase TransactionTset(SysUser sysUser) {
        ResultBase res=new ResultBase();
        res=loginService.login(sysUser);
        sysUser=(SysUser) res.getObj();
        sysUser.setLoginname("123");
        loginService.update(sysUser);
        res=loginService.login(sysUser);
        res.setMessage("成功");
        return res;
    }

结果:方法执行到最后数据才提交 说明事务已经传播到到下一个service 而且属于同一事务  注意:TransactionTset方法@Transactional(propagation = Propagation.REQUIRED)设置使用REQUIRED事务

结论:在同一个事务中 前者改变了数据(新增或者更新) 下面service或者自身的方法再次查询 数据是已经改变了、但是service没有走到最后 数据库的数据还是没变化的

TUser user1=(TUser) operateDao.get(TUser.class, sysUser.getId());
        user1.setPassword("12222");
        operateDao.update(user1);
        user1=(TUser) operateDao.get(TUser.class, sysUser.getId());
        
        Map<String,Class> classMap=new HashMap<String,Class>();
        StringBuffer sql=new StringBuffer("select u.* from t_user as u where id='"+sysUser.getId()+"'");
        PageModel pm=operateDao.searchResultBySql(sql.toString(),null, 0, 0);
/*        StringBuffer sql=new StringBuffer("select {u.*} from t_user as u where id='"+sysUser.getId()+"'");
        classMap.put("u", TUser.class);
        PageModel pm=operateDao.searchResultBySql(sql.toString(),null, classMap, 0, 0);
*/        System.out.println("11");
        System.out.println("11");
        System.out.println("11");
        System.out.println("11");
        return res;

为了测试 同一事务中先更新再查询 结果:

映射对象查询到update后的数据、虽然事务未提交

纯sql查询的是事务未提交前的数据

数据在service介绍提交至数据库

理解spring对事务的处理:传播性的更多相关文章

  1. 通俗的讲法理解spring的事务实现原理

    拿房屋买卖举例,流程:销售房屋 -- 接待员 -- 销售员 -- 财务 售楼处 存放着所有待售和已售的房屋数据(数据源 datasource) 总经理 带领一套自己的班底,下属员工都听自己的,服务于售 ...

  2. 深入理解 Spring 事务原理

    本文由码农网 – 吴极心原创,转载请看清文末的转载要求,欢迎参与我们的付费投稿计划! 一.事务的基本原理 Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供 ...

  3. 深入理解 Spring 事务原理【转】

    本文转自码农网 – 吴极心原创  连接地址:http://www.codeceo.com/article/spring-transactions.html 一.事务的基本原理 Spring事务的本质其 ...

  4. 理解 Spring 事务原理

    转载:https://www.jianshu.com/p/4312162b1458 一.事务的基本原理 Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事 ...

  5. 深入理解Spring事务的那点事

    Spring事务的基本原理 Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事务功能的.对于纯JDBC操作数据库,想要用到事务,可以按照以下步骤进行: 获 ...

  6. Spring事务专题(四)Spring中事务的使用、抽象机制及模拟Spring事务实现

    Spring中事务的使用示例.属性及使用中可能出现的问题 前言 本专题大纲如下: 对于专题大纲我又做了调整哈,主要是希望专题的内容能够更丰富,更加详细,本来是想在源码分析的文章中附带讲一讲事务使用中的 ...

  7. Spring的事务传播性与隔离级别以及实现事物回滚

    一.事务的四个特性(ACID) 原子性(Atomicity):一个事务中所有对数据库的操作是一个不可分割的操作序列,要么全做,要么全部做. 一致性(Consistency): 数据不会因为事务的执行而 ...

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

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

  9. Spring事务的5种隔离级别和7种传播性

    隔离级别 isolation,5 种: ISOLATION_DEFAULT,ISOLATION_READ_UNCOMMITTED,ISOLATION_READ_COMMITTED,ISOLATION_ ...

随机推荐

  1. c#多线程操作测试(阻塞线程,结束任务)

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  2. 2D上下文

    js中说明的上下文表示的意思为C++中作用域(个人理解),因此2D上下文说明的是这个2D的作用域 像素:用来描述图片清晰度的小矩阵 填充和描边 填充:context.fillStyle = " ...

  3. i2c tools 使用

    1.查询罗列出I2C的控制器总线数目 # i2cdetect -l i2c-0 i2c OMAP I2C adapter I2C adapter i2c-1 i2c OMAP I2C adapter ...

  4. jquery autocomplete文本自己主动补全

    文本自己主动补全功能确实非常有用. 先看下简单的效果:(样式不咋会写) 以下介绍几种: 1:jqery-actocomplete.js 这个网上有个写好的实例,上面挺具体的,能够下来执行下就清楚了就不 ...

  5. JAVA File类 分析(二)

    本章開始介绍UNIX文件系统. 文件系统是怎样管理文件的呢?那咱们要先文件的存储介质開始--磁盘 磁盘是计算机系统的一个硬件设备,文件系统为了可以管理磁盘.对其进行了三层抽象(本文全部内容均指UNIX ...

  6. vim基础学习之自动补全功能

    本章我们学习自动补全功能1.自动补全优先从当前的编辑区获得补全列表例如:我们写下如下内容 aaaaa aabbb aaab 当我们再次输入aa,然后我们按下Tab的时候,会弹出一个包含 aaaaa a ...

  7. 怎样通过MSG_WAITALL设置阻塞时间,IO模式精细讲解: MSG_DONTWAIT 、 MSG_WAITALL

    首先给出MSDN上一段设置阻塞超时的代码:(网址为http://social.msdn.microsoft.com/Forums/zh-SG/visualcpluszhchs/thread/3d9da ...

  8. CSS3的属性选择器

    CSS3中新增了许多选择器,今天零度给大家说说CSS3的属性选择器. 与CSS2相比,CSS3新增了3种属性选择器:[attr^=value].[attr$=value].[attr*=value]: ...

  9. 分享一下10个常用jquery片段

      1. 图片预加载 (function($) { var cache = []; // Arguments are image paths relative to the current page. ...

  10. Spring AOP那些学术概念—通知、增强处理连接点(JoinPoint)切面(Aspect)(转)

    1.我所知道的AOP 初看起来,上来就是一大堆的术语,而且还有个拉风的名字,面向切面编程,都说是OOP的一种有益补充等等.一下让你不知所措,心想着:管不得很多人都和我说AOP多难多难.当我看进去以后, ...