幼儿饰品瑜伽美体用品微软
投稿投诉
微软创意
爱情通信
用品婚姻
爱好看病
美体软件
影音星座
瑜伽周边
星座办公
饰品塑形
搞笑减肥
幼儿两性
智家潮品

Seata1。5。2源码学习

  文章有点长,我决定用半个小时来和你分享废话不多说,上代码。
  基于Seata1。5。2,项目中用seataspringbootstarter
  1。SeataDataSourceAutoConfiguration
  SeataDataSourceAutoConfiguration主要是配置数据源代理,可以看到:默认seata。enabled、seata。enableAutoDataSourceProxy、seata。enableautodatasourceproxy都是true只有当classpath中有DataSource时才会进行此配置创建了一个SeataAutoDataSourceProxyCreator,用于自动代理数据源
  先记一下,SeataAutoDataSourceProxyCreator是一个BeanPostProcessor
  刚才new了一个SeataAutoDataSourceProxyCreator,继续看构造方法,默认useJdkProxy是false,excludes为空,dataSourceProxyMode是AT
  构造方法中最重要的一件事情是构造AOP通知(拦截器),这里new了一个SeataAutoDataSourceProxyAdvice
  SeataAutoDataSourceProxyAdvice是一个MethodInterceptor。
  MethodInterceptor是aop中的一个接口,当目标方法被调用时就会调用与之关联的MethodInterceptor的invoke方法
  至此,在构造方法中完成了advisors的赋值,advisors〔〕中有一个DefaultIntroductionAdvisor,DefaultIntroductionAdvisor中引用了SeataAutoDataSourceProxyAdvice
  前面说过,SeataAutoDataSourceProxyCreator是一个BeanPostProcessor,而BeanPostProcessor是BeanFactory中的一个钩子(回调),称之为后置处理器
  AbstractAutoProxyCreatorpostProcessBeforeInstantiation()
  AbstractAutoProxyCreatorpostProcessAfterInitialization()
  AbstractAutoProxyCreatorwrapIfNecessary()
  AbstractAutoProxyCreatorgetAdvicesAndAdvisorsForBean()
  SeataAutoDataSourceProxyCreatorgetAdvicesAndAdvisorsForBean()
  SeataAutoDataSourceProxyCreatorwrapIfNecessary()
  DataSourceProxyHolder维护了数据源对象与数据源代理对象的映射
  至此,数据源代理部分就看完了,下面总结一下:
  1、启动的时候自动配置数据源代理,创建了一个SeataAutoDataSourceProxyCreator
  2、SeataAutoDataSourceProxyCreator在构造方法中创建AOP通知,并赋值给其属性
  3、AbstractAutoProxyCreator是一个抽象类不能被实例化,能实例化的只有SeataAutoDataSourceProxyCreator
  4、SeataAutoDataSourceProxyCreator从AbstractAutoProxyCreator那里继承了很多属性和方法,其中就包括postProcessBeforeInstantiation()、postProcessAfterInitialization()、createProxy()等等
  5、SeataAutoDataSourceProxyCreator间接实现了BeanPostProcessor接口,也就是说它也是BeanPostProcessor的一个实现类
  6、BeanFactory回调所有的BeanPostProcessorpostProcessAfterInitialization()时,就会调用SeataAutoDataSourceProxyCreator的postProcessAfterInitialization()方法,最终会调用wrapIfNecessary()方法
  7、wrapIfNecessary()只关心DataSource对象,它负责为DataSource对象生成代理对象,并且在SeataAutoDataSourceProxyCreator中维护了DataSource对象与SeataDataSourceProxy对象之间的映射关心
  8、创建代理对象时,会给DataSource对象应用AOP拦截器。用AOP的话来讲,就是给目标对象DataSource织入通知,并创建一个被增强的代理对象
  9、通知(拦截器)是SeataAutoDataSourceProxyAdvice,它实现了MethodInterceptor接口
  10、SeataAutoDataSourceProxyAdviceinvoke()方法所做的事情就是,拿到原始DataSource的代理对象,并且在代理对象上调用目标方法
  综上所述,以上做的所有工作都是为了将来调用javax。sql。DataSource上的任意方法时都会被拦截,然后调用其代理对象上对应的方法。而DataSource中最重要的一个方法就是getConnection()
  划重点:将来,所有调用javax。sql。DataSourcegetConnection()都会被拦截,然后在代理对象上执行getConnection(),因此可以这样说
  调javax。sql。DataSourcegetConnection()实际上执行的是io。seata。rm。datasource。SeataDataSourceProxygetConnection()
  2。SeataAutoConfiguration
  SeataAutoConfiguration里面主要是配置GlobalTransactionScanner(全局事务扫描器)
  seata。enabledtrue才会开启SeataAutoConfiguration
  GlobalTransactionScanner也继承自AbstractAutoProxyCreator,同时还实现了InitializingBean接口。BeanFactory在设置了所有bean属性之后会调用InitializingBean的afterPropertiesSet()方法
  GlobalTransactionScannerafterPropertiesSet()
  io。seata。common。DefaultValues中定义了很多默认值
  同样地,因为实现了BeanPostProcessor接口,所以在启动时BeanFactory实例化Bean之后,会调用GlobalTransactionScanner的postProcessAfterInitialization(),尽管这个postProcessAfterInitialization()方法时从AbstractAutoProxyCreator那里继承来的,但是不影响啊,还是会调用GlobalTransactionScanner这个bean的postProcessAfterInitialization()方法。于是,最终又会调wrapIfNecessary()方法。
  GlobalTransactionScannerwrapIfNecessary()
  这里面有一个很重要的逻辑就是,创建了一个GlobalTransactionalInterceptor对象,并赋值给interceptor
  AbstractAutoProxyCreatorgetAdvicesAndAdvisorsForBean()是一个抽象方法,实现在子类GlobalTransactionScanner中
  因此,所有在GlobalTransactionScannerwrapIfNecessary()中被代理的对象,都被应用GlobalTransactionalInterceptor
  GlobalTransactionalInterceptor也是一个MethodInterceptor
  也就是说,目标方法的调用都会转到GlobalTransactionalInterceptorinvoke()上
  GlobalTransactionalInterceptorhandleGlobalTransaction()
  事务执行直接调用TransactionalTemplate的execute()方法
  io。seata。tm。api。TransactionalTemplateexecute()
  io。seata。tm。api。GlobalTransactionContextgetCurrent()获取当前事务
  io。seata。tm。api。TransactionalTemplatebeginTransaction()
  tx是DefaultGlobalTransaction
  io。seata。tm。api。DefaultGlobalTransactionbegin()
  DefaultGlobalTransaction中的TransactionManager是DefaultTransactionManager
  DefaultTransactionManager中提供了事务相关的底层操作
  io。seata。tm。api。DefaultGlobalTransactioncommit()
  io。seata。tm。api。DefaultGlobalTransactionrollback()的逻辑与commit()类似,都是重试调用transactionManager。rollback(xid)
  全局事务扫描器部分的代码就看到这里,下面总结一下:
  1、配置项seata。enabledtrue会触发SeataAutoConfiguration自动配置
  2、SeataAutoConfiguration中创建了一个GlobalTransactionScanner
  3、GlobalTransactionScanner继承了AbstractAutoProxyCreator,并实现InitializingBean接口
  4、初始化TM、RM
  5、由于继承了AbstractAutoProxyCreator,所以BeanFactory会调用GlobalTransactionScanner方法postProcessAfterInitialization(),最终会调用GlobalTransactionScannerwrapIfNecessary()来为目标对象创建代理对象
  6、GlobalTransactionScannerwrapIfNecessary()中创建了一个GlobalTransactionalInterceptor,GlobalTransactionalInterceptor是一个MethodInterceptor
  7、在创建代理对象的时候,在AbstractAutoProxyCreatorwrapIfNecessary()方法中,为代理对象应用GlobalTransactionalInterceptor,于是所有目标对象上的方法调用就会转为调用GlobalTransactionalInterceptorinvoke()
  8、GlobalTransactionalInterceptorinvoke()方法中,首先获取被调用的目标对象的Class和Method对象,然后检查目标方法或类上是否有GlobalTransactional或GlobalLock注解,而且配置项中不能禁用全局事务
  9、如果加了GlobalTransactional注解,则创建一个AspectTransactional,然后开始处理全局事务,默认传播特性是REQUIRED
  10、如果加了GlobalLock注解,则开始处理全局锁
  11、处理全局事务就是直接调用事务模板中的execute方法,TransactionalTemplateexecute()是一个模板方法,其中定义了事务处理的流程。首先开启事务,然后执行业务逻辑,最后提交事务,异常回滚事务。
  12、事务操作是在DefaultGlobalTransaction中处理的,最终处理在DefaultTransactionManager。DefaultTransactionManager负责同步远程调用,向TC发请求来开启、提交、回滚事务等操作
  3。数据库操作执行SQL语句
  通过Java自带的JDBC操作数据库通常是这样的:Class。forName(driverClass);获取ConnectionConnectionconnectionDriverManager。getConnection(url,user,password);创建Statement或者PreparedStatementStatementstmtconnection。createStatement();stmt。execute(sql);PreparedStatementpsconnection。prepareStatement(sql);ps。execute();
  MyBatis底层也是这一套
  接下来看Seata是如何做的
  首先是获取数据库连接Connection,前面已经说过了,调用DataSource的getConnection()方法底层是在代理对象SeataDataSourceProxy上调用getConnection()。SeataDataSourceProxy是接口,如果是AT模式,则这个数据源代理对象是DataSourceProxy
  DataSourceProxygetConnection()获取数据库连接
  ConnectionProxycreateStatement()
  ConnectionProxyprepareStatement()
  PreparedStatementProxy继承自StatementProxy,因此下面就直接看PreparedStatementProxy如何执行SQL
  PreparedStatementProxyexecute()
  ExecuteTemplateexecute()是一个模板方法
  挑一个看看吧,就挑UpdateExecutor
  UpdateExecutor构造方法中一直调父类的构造法,既然如此,那么直接看BaseTransactionalExecutor
  UpdateExecutorexecute()
  这个方法时从BaseTransactionalExecutor那里继承来的,又是一个模板方法,可见设计模式是多么重要
  AbstractDMLBaseExecutordoExecute()
  AbstractDMLBaseExecutorexecuteAutoCommitTrue()
  ConnectionProxychangeAutoCommit()
  现在事务自动提交已经被Seata改成false了
  UpdateExecutorbeforeImage()
  BaseTransactionalExecutorprepareUndoLog()
  接下来,提交事务
  ConnectionProxycommit()
  ConnectionProxyprocessGlobalTransactionCommit()处理全局事务提交
  分支事务提交以后,业务数据更改和undolog就都提交了
  回想一下,为什么在执行业务修改前要先将默认的自动提交改成手动提交,最后再改成自动提交呢?
  因为,要将业务数据修改和插入undolog放在同一个事务里,一起提交
  这一切都归功于代理
  回顾一下整个调用链
  结合之前的案例,AT模式TC、TM、RM三者的交互应该是这样的:
  问题一:为什么在执行的时候,先将数据库自动提交autoCommit设为false,最后再改成true呢?
  答:因为,需要将undolog和业务数据修改放到同一个事务中,这样可以保证业务数据修改成功后undolog必然插入成功,所以Seata要将其改为手动提交。最后再改成true是因为默认autoCommit就是true,这样可以不影响其它业务。
  问题二:什么情况下ConnectionContext中xidnull,且isGlobalLockRequiretrue呢?或者换一种问法,什么情况下不在全局事务中,当仍然需要全局锁呢?
  答:当业务方法上不加GlobalTransactional,而是只加了GlobalLock注解的情况下,就会出现上述情况,也就会执行ConnectionProxyprocessLocalCommitWithGlobalLocks()方法,在事务提交前检查全局锁,这样设计的目的是在AT模式下,不出现脏读、脏写。由于数据源被代理了,当一个加了GlobalTransactional的全局事务,与另一个加了GlobalTransactional或GlobalLock注解的事务在本地事务提交前就会检查全局锁,要先获得全局锁才能提交本地事务,这样就避免了脏读脏写,从而相当于实现了全局事务的读已提交隔离级别。参见:https:seata。iozhcnblogseataatlock。html
  关于Seata1。5。2Client端的源码学习就先到这里,欢迎交流
  如果你都已经看到了这里,不妨给我点个赞吧

50女人冬天烫什么发型?这3种齐肩卷,照着烫就美文:NanaHello,我是娜娜,继续出来值班,那就踏上我们的时尚之路吧。年龄在增长,很多过了50岁的女性在穿衣上不是那么讲究了,可每到冬天,发型是一定要捯饬一下的……或还有DLC!玩家爆银河战士生存恐惧剧情尚未完结10月8日发售的Switch独占游戏《银河战士生存恐惧》相信很多玩家已经通关了!根据之前制作人的说法,本作将会是系列的终章,意味着游戏的剧情将会到此为止。但是2D《银河战士》肯……果然是哈登筹码西蒙斯又涨价了!76人一心想要哈登2。7亿顶薪据ESPN记者爆料,76人关于西蒙斯的交易涨价了,他们想要更多的选秀权或者更多的年轻球员,另外一种交易方法就是除非获得即战力更强的球员,可以球队获得总冠军可以考虑交易。76人管……iOS15。2。1能升级吗?9部iPhone续航对比,这4部每当苹果升级iOS的时候,果粉都十分关心,因为果粉对于新iOS的升级一般都会持有怀疑态度。毕竟iOS的每次更新并不都是好事情,有的时候反而会对iPhone的使用体验产生相反的影……7人爆砍108分,深圳队打疯了!沈梓捷振臂高呼,反超广东队升北京时间12月25日,CBA20212022赛季第2阶段赛程正式打响,在首场对决中,山西队以142:131战胜了福建队,而接下来,深圳队迎来同曦队的挑战!深圳队在第1阶段……莫兰特轰3866仍无缘今日最佳!对不起,你碰到篮网队史第一人北京时间1月22日,NBA常规赛继续进行,联盟总共安排11了组对决,莫兰特、詹姆斯、努尔基奇、字母哥、库里、特雷杨、巴恩斯、戈贝尔等球星都有不俗的表现。比如灰熊队的莫兰特,在灰……夏日跑马梁跑马梁,秦岭光鹿跑兵冰(光头山、鹿角梁、跑马梁、兵马营、冰晶顶)的一个山峰,海拔2680米。最近下雨很多,一直想走一个强度稍微大的线路,计划一直推迟。好不容易到了中秋节假……法甲0大胜兰斯迎13轮不败北京时间1月24日凌晨3点45分,202122赛季法甲联赛第22轮的压轴大戏在王子公园球场拉开帷幕,领头羊巴黎圣日耳曼主场对阵兰斯。维拉蒂上半场破门,拉莫斯下半场收获巴黎生涯处……灰熊11连胜,掘金32分大胜开拓者,雄鹿轻取勇士,东西部最新美职篮常规赛继续进行,今天只有5场赛事:灰熊豪取11连胜;掘金32分大胜开拓者;雄鹿轻取勇士;快船惨败鹈鹕;篮网不敌西部倒数第二。比赛回顾灰熊116:108险胜森林狼,豪……熊竞楠完胜日本挑战者,第六次卫冕世界冠军国际知名体育IPONE冠军赛于2022年1月14日晚在新加坡举办了ONE:重拳出击大型格斗赛事。在刚刚结束的女子草量级世界冠军赛中,中国选手熊竞楠五回合一致判定战胜来自日本的挑……打不赢伊藤不重要,刘诗雯不忘初心,快乐乒乓就行,伊藤交给师妹近日,小言看到一个乒乓关于刘诗雯的话题,说她没机会打败伊藤伊藤美诚。到了小枣这个时候,赢不赢伊藤还有意义吗?小枣快31岁了,名副其实老将,而伊藤美诚21岁,如此年龄差,小……原神游戏培养成本分析我甚至觉得原神是培养成本相当低的游戏了。只有没有开放120级的fgo培养成本比它低,毕竟fgo到手就拉满90很正常。原神,如果是指拉到90满级310角色,那肯定高啊……
皮卡的春天真的要来了!比亚迪新能源皮卡曝光,太适合露营了!比亚迪这几年的销量非常不错,而且也在不断的朝着高端的方向发展。而在最近比亚迪居然曝光了一款皮卡车型,结合最近很多品牌都在推出类似的家用皮卡,可能皮卡的春天真要来了。目前比……新华全媒国际湿地城市一线直击立冬时节,登上哈尔滨松浦大桥,在下桥口顺台阶而下,映入眼帘的是大片金黄色的芦苇荡,白色芦花点缀其中迎风招展,透过澄澈的水面依稀可见水草和水藻。在位于哈尔滨市松花江北面的阿勒锦岛……华为watchgtcyber和gt3区别是什么?gtcybe在华为PocketS及全场景新品发布会上,全新的智能手表华为WATCHGTCyber也和大家见面了,这是华为第一款可以更换表壳的产品,那么其和华为WATCHGT3相比有什么区别……iPhone计算机隐藏9大超实用技巧科学计算器删除1位数表白很多人在打开iPhone苹果手机计算器时,都会感觉比起安卓手机的计算器太过于简单,只能进行简单的加减乘除,其实iPhone手机自带的计算器隐藏了很多实用的功能。一、iPh……在世界北极熊之都,北极熊正在快速消失极目新闻记者李力力胡秀文据《卫报》12月24日报道,加拿大一项政府调查显示,该国哈得孙湾西部(位于北极南缘)的北极熊正在快速消失,尤其是母熊和幼崽的数量急剧下降。哈……房价的拐点在2023年头条创作挑战赛2023年将是人口拐点,政策拐点,也是房地产市场和房价的拐点。大家好,我是大海青岛,这期内容我主要通过一个视频从不同的维度给你讲解,2023年将会是房……现在,与李冰冰周冬雨刘雯龚俊一起进入VOGUE世界1892年VOGUE创刊,如今已有整整130年的历史。而从今天开始至10月23日登陆上海艺仓美术馆的VOGUEWorld展览,则可以带你最近距离地领略百年来时尚艺术与女性风貌的……母亲去世留下近150万遗产,写了9份遗嘱全给2女儿,一分不给歌德说:无论是国王还是农夫,只要家庭和睦,他便是最幸福的人。一家人温馨和睦,哪怕日子不富裕,也能过得热气腾腾;但如果,家庭中矛盾纷争不断,即便是日入斗金,也会把生活折腾得……荣耀X40真机曝光,或搭载骁龙695处理器在近日的宣传预热过程中,荣耀官方较为意外的提前公布了荣耀X40的真机实拍。根据实拍视频截图来看,荣耀X40的背面设计,除了下方LOGO为HONOR字样外,与华为Mate4……电视推荐买电视不踩坑现在的电视用的配件都差不多,挑选电视我认为芯片、内存、亮度、刷新率是非常关键的,当然系统也很重要;刷新率达到60赫兹,可以满足看电视的需求,当然高了会更好;在2000元以内选择……魔力宝贝手游转职的前置条件?哈喽,大家好!这期给大家讲下魔力宝贝手游中职业转职的要求及注意事项。一转要求:1,玩家等级20级2,声望称号呢哺的歌声(声望3000)3,完成【树精长老……刚刚,海航董事长又换人了刚刚,海航公告,公司董事会同意选举丁拥政先生担任公司董事长、法定代表人职务。今天,海南航空召开第十届董事会第一次会议,会议了几个议案,包括:1、关于选举丁拥政先生担……
友情链接:易事利快生活快传网聚热点七猫云快好知快百科中准网快好找文好找中准网快软网