Spring-tx

spring-tx,spring-jdbc模块笔记,只涉及事务部分

核心类

@EnableTransactionManagement:引入TransactionManagementConfigurationSelector,根据参数判断proxy/aspectj载入不同的解析对象,proxy模式下载入AutoProxyRegistrar和ProxyTransactionManagementConfiguration.

AutoProxyRegistrar:将InfrastructureAdvisorAutoProxyCreator加入到容器中.它将框架基础设施Advisor(role=BeanDefinition.ROLE_INFRASTRUCTURE)生成对应的aop代理

ProxyTransactionManagementConfiguration:载入了基于注解的aop基础设施Bean.主要是将解析注解的Advisor对象加入到容器中

TransactionAttributeSource:事务源信息的获取策略接口,载入的是AnnotationTransactionAttributeSource类,用于处理@Transaction注解
TransactionInterceptor-TransactionAspectSupport-invokeWithinTransaction执行流程

BeanFactoryTransactionAttributeSourceAdvisor:通过StaticMethodMatcherPointcut将方法级过滤转移到TransactionAttributeSource进行判断,advice部分转到TransactionInterceptor进行实现.自身作为advisor加入到容器

事务管理器-事务的流程抽象

PlatformTransactionManager:事务管理器接口定义,使用较多的是DataSourceTransactionManager.它是以DataSource中的connection抽象的事务对象

TransactionStatus:存储事务对象,挂起的上一个事务对象以及额外事务属性的接口.它是主要的中间数据,用于存储原始连接信息以便后续的恢复连接信息

TransactionDefinition:事务属性接口.传播属性,隔离级别,只读等.它的实现主要是DefaultTransactionDefinition

TransactionTemplate:继承DefaultTransactionDefinition,自身即含有事务状态,同时引入了PlatformTransactionManager进行事务操作,还实现了
TransactionOperations接口,提供了手工事务操作入口.

核心流程

首先通过TransactionManager的getTransaction(td)方法获得TransactionStatus对象,后面执行对应的回调方法,如果出异常那么回滚,如果正常执行完成,那么提交操作,这两个操作都需要之前返回的TransactionStatus对象作为入参.

以DataSourceTransactionManager为例,描述完整的事务管理过程
getTransaction()方法,先通过doGetTransaction抽象方法获取事务对象,事务对象是子类自己定义的,这里用的是DataSourceTransactionObject类,在doGetTransaction方法只是新建了DataSourceTransactionObject对象,尝试通过ThreadLocal获取之前的ConnectionHolder设置到当前事务对象中.
然后判断当前线程是否存在被激活的事务(这里根据是否存在当前事务对传播属性进行了实现)

如果有事务
那么检查事务传播行为,做出对应的操作,直接返回结果
事务传播行为对应的操作(获取连接=实际根据属性进行连接配置)
PROPAGATION_NEVER-抛异常
PROPAGATION_NOT_SUPPORTED-挂起当前事务,生成一个空的DefaultTransactionStatus返回(在非事务中执行)
PROPAGATION_REQUIRES_NEW-挂起当前事务,将原事务对象与被挂起的资源放入DefaultTransactionStatus对象,并获取连接(新建事务)
PROPAGATION_NESTED-不挂起当前事务,将原事务对象放入DefaultTransactionStatus对象,并获取连接(支持嵌套才可以,如果是DataSourceTM那么实际上还是同一连接)
其他情况-不挂起当前事务,将原事务对象放入DefaultTransactionStatus对象,直接返回,不获取连接(支持当前事务运行PROPAGATION_REQUIRED或PROPAGATION_SUPPORTS)

如果没有事务
根据对应的传播属性做出对应的操作并返回
PROPAGATION_MANDATORY-抛异常
PROPAGATION_REQUIRED&PROPAGATION_REQUIRES_NEW&PROPAGATION_NESTED-那么执行以下操作
新建TransactionStatus对象(DefaultTransactionStatus),执行doBegin抽象方法,这里doBegin方法先判断事务对象是否有连接,如果没有连接,那么调用DataSource.getConnection获取一个新连接并包装成ConnectionHolder对象放入事务对象内.然后对连接属性进行设置,有隔离级别,手动提交.还要读取Definition信息设置ConnectionHolder对象的属性.同时将之前的连接信息存储到事务对象中,用于后续提交或者回滚后恢复连接属性操作.后面继续判断如果是新连接,那么线程绑定事务对象,同时设置事务激活状态,绑定事务隔离级别,只读属性,名称等.返回TransactionStatus对象,让使用者在可以拿到事务的属性信息.结束创建事务流程.
其他情况-生成一个空的DefaultTransactionStatus返回(在非事务中执行,如PROPAGATION_SUPPORTS,PROPAGATION_NOT_SUPPORTED)

中间在事务中执行对应的sql.

详细说下这里连接对象的获取过程.对于mybatis-spring来说,使用的是SpringManagedTransaction对象进行管理DataSource来获取连接的,这里的getConnection会转到DataSourceUtils的getConnection中,它优先判断从绑定线程中可以获取对应的ConnectionHolder,并且事务是被激活的状态,那么从ConnectionHolder拿出连接直接返回,如果不是的话就获取真实连接,再判断当前事务是否激活,如果是被激活的,那么注册ConnectionSynchronization(用于清理资源)和将ConnectionHolder绑定到当前线程.最后返回连接对象

最后如果抛出异常
回滚操作.先触发绑定线程中的BeforeCompletion回调,然后调用connection的rollback,根据有无异常,触发AfterCompletion的回调并传入不同参数.最后触发AfterCompletion的回调

如果没有抛出异常
提交.检查是否有本地/全局回滚标志,如果有的话调用回滚操作,如果没有,触发BeforeCommit回调,然后BeforeCompletion回调,然后调用connection的commit.如果有异常触发回滚,如果没有,触发AfterCommit回调,最后触发AfterCompletion回调,然后进行清理过程,清理掉所有线程绑定的对象,恢复连接属性(自动提交,隔离级别,只读属性),恢复之前挂起的事务.当前事务结束

事务特点

1.原子性:一个事务中所有对数据库的操作是一个不可分割的操作序列,要么全做要么全不做
2.一致性:数据不会因为事务的执行而遭到破坏
3.隔离性:一个事物的执行,不受其他事务的干扰,即并发执行的事物之间互不干扰
4.持久性:一个事物一旦提交,它对数据库的改变就是永久的。

七个事务传播属性—传播属性的实现是spring实现的,有些传播属性(比如PROPAGATION_NESTED)主要是JTA考虑的
 PROPAGATION_REQUIRED -- 支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
 PROPAGATION_SUPPORTS -- 支持当前事务,如果当前没有事务,就以非事务方式执行。
 PROPAGATION_MANDATORY -- 支持当前事务,如果当前没有事务,就抛出异常。
 PROPAGATION_REQUIRES_NEW -- 新建事务,如果当前存在事务,把当前事务挂起。
 PROPAGATION_NOT_SUPPORTED -- 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
 PROPAGATION_NEVER -- 以非事务方式执行,如果当前存在事务,则抛出异常。
 PROPAGATION_NESTED--如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。

五种隔离级别—隔离级别的实现是依靠数据库自身实现的
隔离级别是指若干个并发的事务之间的隔离程度。
ISOLATION_DEFAULT--这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别.另外四个与JDBC的隔离级别相对应;
ISOLATION_READ_UNCOMMITTED--这是事务最低的隔离级别,它充许别外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻像读。
ISOLATION_READ_COMMITTED--保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据。这种事务隔离级别可以避免脏读出现,但是可能会出现不可重复读和幻像读。
ISOLATION_REPEATABLE_READ--这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。它保证了一个事务中的所有读取操作时一致的结果,不受事务中其他事务提交的影响.但是会产生幻读,比如说范围查询时,每次查询结果是一致的,但是其他事务新插入了符合条件的行,导致执行的范围更新比查询结果多,就像产生的幻觉.部分数据库在RR级别已经可以解决幻读的问题了
ISOLATION_SERIALIZABLE--这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。除了防止脏读,不可重复读外,还避免了幻像读。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容

  • spring transaction 笔记 事务的特性(ACID) 原子性(Atomicity)、一致性(Cons...
    NoSuchElementEx阅读 6,029评论 0 0
  • 一、PlatformTransactionManager 1、架构设计理念让事务的关注点与数据访问关注点分离...
    七离_82cd阅读 7,277评论 0 3
  • ORA-00001: 违反唯一约束条件 (.) 错误说明:当在唯一索引所对应的列上键入重复值时,会触发此异常。 O...
    我想起个好名字阅读 5,169评论 0 9
  • 事务的嵌套概念 所谓事务的嵌套就是两个事务方法之间相互调用。spring事务开启 ,或者是基于接口的或者是基于类的...
    jackcooper阅读 1,412评论 0 10
  • 黯然销魂者 唯别而已矣 生离死别 又岂止是黯然销魂呢 亲爱的 还记得我们一起去湿地公园 你简直有才到飞起 你就这样...
    重复走阅读 104评论 0 0