• spring源码 — 五、事务


    spring提供了可配置、易扩展的事务处理框架,本文主要从一下几个方面说明spring事务的原理

    • 基本概念
    • 事务配置解析
    • 事务处理过程

    基本概念

    事务隔离级别

    在同时进行多个事务的时候,可能会出现脏读、不可重复读、幻读四种情况,数据库分别有四种隔离级别处理这些情况。Spring中TransactionDefinition定义了事务的隔离级别和传播属性,隔离级别有

    1. ISOLATION_DEFAULT:PlatforTransactionManager默认的隔离级别,也就是数据库默认的隔离级别,下面四中分别对应数据库四中隔离级别
    2. ISOLATION_READ_UNCOMMITED:在另外一个事务未提交的时候可以读取另一个事务中的数据,会出现脏读、不可重复读、幻读,系统开销最小,没有加锁
    3. ISOLATION_READ_COMMITED:在另外一个事务提交之后才可以读取数据,防止了脏读,会出现不可重复读、幻读
    4. ISOLATION_REPEATABLE_READ:防止了脏读、不可重复读(在一个事物读取数据之后,第一个事务提交数据,第一个事务再次读取数据,发现前后不一致),会出现幻读,读不加锁,增删改加锁
    5. ISOLATION_SERIALIZABLE:可以防止脏读、不可重复读、幻读(第一个事务修改涉及到了数据库中全部行,第二个事务向表中插入一行,第一个事务会发现表中还有没有修改的行)

    spring事务传播属性

    传播属性:定义了多层事务时候的行为,spring的TransactionDefinition定义了7种事务传播行为

    1. PROPAGETION_REQUIRED:如果已经有事务,则使用当前事务,如果没有则新开一个事务
    2. PROPAGETION_SUPPORT:如果已经有事务则事务的执行,如果没有则非事务地执行
    3. PROPAGERION_MANDATORY:如果有事务则支持事务,否则抛出异常
    4. PROPAGETION_REQUIRES_NEW:总是开启一个新的事务,如果已经有事务,则挂起当前事务
    5. PROPAGETION_NOT_SUPPORT:总是非事务执行,如果有事务则挂起
    6. PROPAGETION_NEVER:总是非事务执行,如果有事务则抛出异常
    7. PEOPAGETION_NESTED:嵌套事务(内层事务不影响外层事务,外层事务失败会回滚内层事务),如果有事务,则嵌套在当前事务中执行,如果没有事务则按照PROPAGETION_REQUIRED的方式运行

    事务配置解析

    spring支持编程式事务,也支持声明式事务,这里以声明式事务的配置为例。

    在配置事务管理器的时候配置为使用cglib生成代理

    <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
    

    上面xml配置的作用

    # tx命名空间的处理类
    org.springframework.transaction.config.TxNamespaceHandler
    # annotation-driven标签的解析类
    org.springframework.transaction.config.AnnotationDrivenBeanDefinitionParser
    # 解析标签annotation-driven的方法
    org.springframework.transaction.config.AnnotationDrivenBeanDefinitionParser.AopAutoProxyConfigurer#configureAutoProxyCreator
    

    解析该标签的时候做了以下的事

    1. 注册org.springframework.aop.config.AopConfigUtils#AUTO_PROXY_CREATOR_BEAN_NAME,org.springframework.aop.framework.autoproxy.InfrastructureAdvisorAutoProxyCreator
    2. 设置InfrastructureAdvisorAutoProxyCreator这个bean对应的属性,proxyTargetClass,exposeProxy
    3. 注册bean:AnnotationTransactionAttributeSource
    4. 注册bean:TransactionInterceptor
    5. 注册bean:TransactionAttributeSourceAdvisor
    6. 注册组合component:CompositeComponentDefinition

    上面解析标签的时候注入的这些bean在getBean的时候会起作用,在getBean的时候会判断是否需要返回包装后的bean,也就是org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary方法,找到所有的advisor(顺便完成初始化),然后判断找出所有可以应用到该类的advisor(org.springframework.aop.support.AopUtils#findAdvisorsThatCanApply),然后利用可用的advisor创建proxy(org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createProxy),这个proxy就是原来类的代理,在请求该类的方法的时候是通过代理进行的,在代理中会判断是否有事务,是否需要开启事务

    事务处理过程

    Spring 事务处理是基于AOP实现的,为事务方法所在类生成一个代理类,在调用事务方法的时候实际会调用代理类的代理方法,这里就是

    org.springframework.transaction.interceptor.TransactionInterceptor#invoke
    

    spring事务

    在看spring事务处理流程之前,我们先回顾下直接使用jdbc编程的时候使用事务的流程

    1. 拿到数据库连接
    2. 设置数据库连接为非自动提交
    3. 执行事务操作
    4. 提交事务

    spring事务处理的流程也基本相似,只是做了一些封装

    1. 拿到数据库连接,需要判断当前事务的传播级别,有些传播级别需要新的数据库连接开启新的事务
    2. 设置数据库连接为非自动提交
    3. 执行事务操作
    4. 执行事务提交前的一些回调方法,比如:beforeCommit
    5. 提交事务,判断是否有异常,是需要回滚还是提交
    6. 执行事务提交后的一个方法,比如:afterCommit

    总结

    spring事务在屏蔽了一些繁琐逻辑的同时,也提供了比较好的扩展性,比如支持自定义数据源,自定义事务管理器,而且支持在事务执行前后加入自己的回调用方法。

  • 相关阅读:
    网络传输协议 UDP & TCP 详解
    OSI 七层协议
    (01day)python接口测试
    Python2和Python3的区别,以及为什么选Python3的原因
    JAVA反编译工具
    JAR反编译工具
    webdriver19-witchto方法
    webdriver实例14-Xpath定位的几种方法
    webdirver实例1--查找元素
    Qt插件开发
  • 原文地址:https://www.cnblogs.com/sunshine-2015/p/10562202.html
Copyright © 2020-2023  润新知