生活工程体验信仰哲学精神
投稿投诉
精神世界
探索历史
哲学文学
艺术价值
信仰创造
境界审美
体验技术
技能工具
工程信息
医学生产
生活运用
操作能力

spring事务失效的几种场景以及原因

12月16日 相思宫投稿
  前言
  spring事务失效场景可能大家在很多文章都看过了,所以今天就水一篇,看大家能不能收获一些不一样的东西。直接进入主题spring事务失效场景以及原因1、场景一:service没有托管给springpublicclassTranInvalidCaseWithoutInjectSpring{privateUserServiceuserSpublicTranInvalidCaseWithoutInjectSpring(UserServiceuserService){this。userServiceuserS}Transactionalpublicbooleanadd(Useruser){booleanisSuccessuserService。save(user);inti10;returnisS}}TestpublicvoidtestServiceWithoutInjectSpring(){booleanrandomBooleannewRandom()。nextBoolean();TranInvalidCaseWithoutInjectSpringtranInvalidCaseWithoutInjectSif(randomBoolean){tranInvalidCaseWithoutInjectSpringapplicationContext。getBean(TranInvalidCaseWithoutInjectSpring。class);System。out。println(service已经被spring托管);}else{tranInvalidCaseWithoutInjectSpringnewTranInvalidCaseWithoutInjectSpring(userService);System。out。println(service没被spring托管);}booleanisSuccesstranInvalidCaseWithoutInjectSpring。add(user);Assert。assertTrue(isSuccess);}
  失效原因:spring事务生效的前提是,service必须是一个bean对象
  解决方案:将service注入spring2、场景二:抛出受检异常ServicepublicclassTranInvalidCaseByThrowCheckException{AutowiredprivateUserServiceuserSTransactionalpublicbooleanadd(Useruser)throwsFileNotFoundException{booleanisSuccessuserService。save(user);newFileInputStream(1。txt);returnisS}}TestpublicvoidtestThrowCheckException()throwsException{booleanrandomBooleannewRandom()。nextBoolean();booleanisSTranInvalidCaseByThrowCheckExceptiontranInvalidCaseByThrowCheckExceptionapplicationContext。getBean(TranInvalidCaseByThrowCheckException。class);if(randomBoolean){System。out。println(配置Transactional(rollbackForException。class));isSuccesstranInvalidCaseByThrowCheckException。save(user);}else{System。out。println(配置Transactional);tranInvalidCaseByThrowCheckException。add(user);}Assert。assertTrue(isSuccess);}
  失效原因:spring默认只会回滚非检查异常和error异常
  解决方案:配置rollbackFor3、场景三:业务自己捕获了异常Transactionalpublicbooleanadd(Useruser){booleanisSuccessuserService。save(user);try{inti10;}catch(Exceptione){}returnisS}TestpublicvoidtestCatchExecption()throwsException{booleanrandomBooleannewRandom()。nextBoolean();booleanisSTranInvalidCaseWithCatchExceptiontranInvalidCaseByThrowCheckExceptionapplicationContext。getBean(TranInvalidCaseWithCatchException。class);if(randomBoolean){randomBooleannewRandom()。nextBoolean();if(randomBoolean){System。out。println(将异常原样抛出);tranInvalidCaseByThrowCheckException。save(user);}else{System。out。println(设置TransactionAspectSupport。currentTransactionStatus()。setRollbackOnly(););tranInvalidCaseByThrowCheckException。addWithRollBack(user);}}else{System。out。println(业务自己捕获了异常);tranInvalidCaseByThrowCheckException。add(user);}Assert。assertTrue(isSuccess);}
  失效原因:spring事务只有捕捉到了业务抛出去的异常,才能进行后续的处理,如果业务自己捕获了异常,则事务无法感知
  解决方案:
  1、将异常原样抛出;
  2、设置TransactionAspectSupport。currentTransactionStatus()。setRollbackOnly();4、场景四:切面顺序导致ServicepublicclassTranInvalidCaseWithAopSort{AutowiredprivateUserServiceuserSTransactionalpublicbooleansave(Useruser){booleanisSuccessuserService。save(user);try{inti10;}catch(Exceptione){thrownewRuntimeException();}returnisS}}AspectComponentSlf4jpublicclassAopAspect{Around(valueexecution(com。github。lybgeek。transcase。aopsort。。。(。。)))publicObjectaround(ProceedingJoinPointpjp){try{System。out。println(这是一个切面);returnpjp。proceed();}catch(Throwablethrowable){log。error({},throwable);}}}
  失效原因:spring事务切面的优先级顺序最低,但如果自定义的切面优先级和他一样,且自定义的切面没有正确处理异常,则会同业务自己捕获异常的那种场景一样
  解决方案:
  1、在切面中将异常原样抛出;
  2、在切面中设置TransactionAspectSupport。currentTransactionStatus()。setRollbackOnly();5、场景五:非public方法ServicepublicclassTranInvalidCaseWithAccessPerm{AutowiredprivateUserServiceuserSTransactionalprotectedbooleansave(Useruser){booleanisSuccessuserService。save(user);try{inti10;}catch(Exceptione){thrownewRuntimeException();}returnisS}}publicclassTranInvalidCaseWithAccessPermTest{publicstaticvoidmain(String〔〕args){ConfigurableApplicationContextcontextSpringApplication。run(Application。class);TranInvalidCaseWithAccessPermtranInvalidCaseWithAccessPermcontext。getBean(TranInvalidCaseWithAccessPerm。class);booleanisSuccesstranInvalidCaseWithAccessPerm。save(UserUtils。getUser());System。out。println(isSuccess);}}
  失效原因:spring事务默认生效的方法权限都必须为public
  解决方案:
  1、将方法改为
  2、修改TansactionAttributeSource,将publicMethodsOnly改为false【这个从源码跟踪得出结论】
  3、开启AspectJ代理模式【从spring文档得出结论】文档如下
  MethodvisibilityandTransactional
  Whenusingproxies,youshouldapplytheTransactionalannotationonlytomethodswithpublicvisibility。Ifyoudoannotateprotected,privateorpackagevisiblemethodswiththeTransactionalannotation,noerrorisraised,buttheannotatedmethoddoesnotexhibittheconfiguredtransactionalsettings。ConsidertheuseofAspectJ(seebelow)ifyouneedtoannotatenonpublicmethods。
  具体步骤:
  1、在pom引入aspectjrt坐标以及相应插件dependencygroupIdorg。aspectjgroupIdaspectjrtartifactIdversion1。8。9versiondependencyplugingroupIdorg。codehaus。mojogroupIdaspectjmavenpluginartifactIdversion1。9versionconfigurationshowWeaveInfotrueshowWeaveInfogroupIdorg。springframeworkgroupIdspringaspectsartifactIdaspectLibraryaspectLibrariesconfigurationexecutionsexecutiongoalsgoalcompilegoal!usethisgoaltoweaveallyourmainclassesgoaltestcompilegoal!usethisgoaltoweaveallyourtestclassesgoalsexecutionexecutionsplugin
  2、在启动类上加上如下配置EnableTransactionManagement(modeAdviceMode。ASPECTJ)
  注:如果是在idea上运行,则需做如下配置
  4、直接用TransactionTemplate
  示例:AutowiredprivateTransactionTemplatetransactionTprivatevoidprocess(){transactionTemplate。execute(newTransactionCallbackWithoutResult(){OverrideprotectedvoiddoInTransactionWithoutResult(TransactionStatusstatus){processInTransaction();}});}6、场景六:父子容器
  失效原因:子容器扫描范围过大,将未加事务配置的serivce扫描进来
  解决方案:
  1、父子容器个扫个的范围;
  2、不用父子容器,所有bean都交给同一容器管理
  注:因为示例是使用springboot,而springboot启动默认没有父子容器,只有一个容器,因此就该场景就演示示例了7、场景七:方法用final修饰Transactionalpublicfinalbooleanadd(Useruser,UserServiceuserService){booleanisSuccessuserService。save(user);try{inti10;}catch(Exceptione){thrownewRuntimeException();}returnisS}
  失效原因:因为spring事务是用动态代理实现,因此如果方法使用了final修饰,则代理类无法对目标方法进行重写,植入事务功能
  解决方案:
  1、方法不要用final修饰8、场景八:方法用static修饰Transactionalpublicstaticbooleansave(Useruser,UserServiceuserService){booleanisSuccessuserService。save(user);try{inti10;}catch(Exceptione){thrownewRuntimeException();}returnisS}
  失效原因:原因和final一样
  解决方案:
  1、方法不要用static修饰9、场景九:调用本类方法publicbooleansave(Useruser){returnthis。saveUser(user);}TransactionalpublicbooleansaveUser(Useruser){booleanisSuccessuserService。save(user);try{inti10;}catch(Exceptione){thrownewRuntimeException();}returnisS}
  失效原因:本类方法不经过代理,无法进行增强
  解决方案:
  1、注入自己来调用;
  2、使用EnableAspectJAutoProxy(exposeProxytrue)AopContext。currentProxy()10、场景十:多线程调用Transactional(rollbackForException。class)publicbooleansave(Useruser)throwsExecutionException,InterruptedException{FutureBooleanfutureexecutorService。submit((){booleanisSuccessuserService。save(user);try{inti10;}catch(Exceptione){thrownewException();}returnisS});returnfuture。get();}
  失效原因:因为spring的事务是通过数据库连接来实现,而数据库连接spring是放在threadLocal里面。同一个事务,只能用同一个数据库连接。而多线程场景下,拿到的数据库连接是不一样的,即是属于不同事务11、场景十一:错误的传播行为Transactional(propagationPropagation。NOTSUPPORTED)publicbooleansave(Useruser){booleanisSuccessuserService。save(user);try{inti10;}catch(Exceptione){thrownewRuntimeException();}returnisS}
  失效原因:使用的传播特性不支持事务12、场景十二:使用了不支持事务的存储引擎
  失效原因:使用了不支持事务的存储引擎。比如mysql中的MyISAM13、场景十三:数据源没有配置事务管理器
  注:因为springboot,他默认已经开启事务管理器。org。springframework。boot。autoconfigure。jdbc。DataSourceTransactionManagerAutoConfiguration。因此示例略过14、场景十四:被代理的类过早实例化ServicepublicclassTranInvalidCaseInstantiatedTooEarlyimplementsBeanPostProcessor,Ordered{AutowiredprivateUserServiceuserSTransactionalpublicbooleansave(Useruser){booleanisSuccessuserService。save(user);try{inti10;}catch(Exceptione){thrownewRuntimeException();}returnisS}OverridepublicintgetOrder(){return1;}}
  失效原因:当代理类的实例化早于AbstractAutoProxyCreator后置处理器,就无法被AbstractAutoProxyCreator后置处理器增强总结
  本文列举了14种spring事务失效的场景,其实这14种里面有很多都是归根结底都是属于同一类问题引起,比如因为动态代理原因、方法限定符原因、异常类型原因等demo链接
  https:github。comlybgeekspringbootlearningtreemasterspringboottransactioninvalidcase
投诉 评论

职业联赛一夜回到解放前,限薪令后,被曝下一步限制外援人数据报道,中国足球史上最强限薪令马上就要公布,其实这也是足协谋划已久的,早在上个赛季就已经制定出了具体内容,只待官宣。基本内容如下1、国内球员最高年薪不得高于税前300w……从11,梅西爆发!不到6成控球造19射,卫冕冠军跌至第11名法甲第23轮比赛,卫冕冠军里尔对阵大巴黎,这场比赛之前,外界其实一开始并不完全看好大巴黎能取胜战胜对手,就管从整体实力来看,大巴黎明显是碾压里尔队,但是无论怎么说,里尔都是法甲……这个12月,你期待怎样的幸福来敲门?伴随着渐降的气温,我们来到了2022年的尾声。12月,一个充满了温暖与期待的月份,平安夜、圣诞节、元旦。。。。。。不断上演的温馨故事,都在诉说着关于节日仪式感的重要性。……看书又有新选择,华为出墨水屏电纸书阅读器了MatePadPa又是先在海外首发的华为新品:MatePadPaper鸿蒙系统电纸书阅读器。对此我有点不爽啊,怎么老是在国外首发,什么鬼,苹果都是中国大陆首发的。上月就在海外发布的产品,貌……恒星和行星之间可以转换吗,什么情况下变为恒星?一般来说,恒星有三个不同的结局,即老红矮星,最终变成白矮星的黄矮星和超新星爆发超级巨星,其中超新星爆发有两个结果,一个是黑洞,另一个是中子星,但事实上,在真正意义上仍然有两个结……甘凤池技击散手,收藏本篇,就是收藏了其全部的55招格斗精华甘凤池,江苏南京人,清代著名武术家,精内外家拳,善导引之术。江湖人称江南大侠,著有《花拳总讲法》。《花拳总讲法》中的招式共计一百二十招散手,七十二招擒拿,三十六招腿法,二十四招……炖骨头汤,谨记2不放3窍门,骨汤浓白,汤鲜味美不油腻炖骨头汤,谨记2不放3窍门,骨汤浓白,汤鲜味美不油腻春天的确是很有特色的,虽然温度比冬天高了不少,但是风也很大,每天出门被刮得头发乱糟糟的,而且天气特别干燥,最近感觉嘴唇……spring事务失效的几种场景以及原因前言spring事务失效场景可能大家在很多文章都看过了,所以今天就水一篇,看大家能不能收获一些不一样的东西。直接进入主题spring事务失效场景以及原因1、场景一:ser……科学家发现4000万年前被遗忘大陆,始新世末期生物大灭绝科学家们重新发现了一个4000万年前被遗忘的大陆,它可能是让亚洲哺乳动物栖息在南欧的桥梁。一份新闻稿显示,新发现的陆地通道可能改变了无数古代物种的路线。许多亚洲哺乳动物将……中路天克小鱼人的存在,阿狸发条不算什么,选他小鱼没有生存空间哈喽,大家好!我是老张。众所周知,中路的小鱼人应该算的上是峡谷当中爆发能力最高的刺客之一了,在发育良好的前提下,一个大招甚至可以直接咬掉脆皮大半管的血量,秒杀C位可能就是一眨眼……过年蒸馒头,掌握4个技巧,半小时发好面,个个松软好吃,不回缩过年蒸馒头,掌握4个技巧,半小时发好面,个个松软好吃,不回缩过年了,很多地方都有蒸馒头的习俗,一次蒸上好几锅,能吃到正月十五。俗话说二十八,把面发,大家会发面吗?腊……大量iOS粉跑路鸿蒙鸿蒙系统还藏着这3大杀手锏上周华为鸿蒙系统又进行了大范围的更新,同事老高兴高采烈地向我们展示鸿蒙系统的新功能,直呼真香,要知道他以前可是果粉。不仅是他,从网上也可以看到大量网友从使用iOS系统,纷……
九月起,做好资产贬值准备?两大信号出现,楼市泡沫可能破灭红楼梦单是命意就因读者的眼光而有种种党章造句用党章造句大全黎巴嫩富人如何变得更富有?渔民发现了大麋鹿的遗骸现存于的车库中肩周炎的治疗方法肩周炎的种疗法梦幻西游全民PK争霸赛王者诞生引关注,杨洋Uzi再决胜负惊喜夏天的雷阵雨企业文化培训总结体会母乳喂养时需要哪些工具商场发生抢劫怎么处理清平乐张茂则为什么自杀赵祯是怎样劝回张茂则揭秘宝宝自制力培养大方式子女对父母抚养协议需要包含哪些内容?版权的著作权人和作者有啥区别从正午乔家的儿女探讨为何影视剧中小人物越来越少?2014年感动中国观后感全险没用!教你花最少的钱买最有用的车险!企业如何留住人才四川一男子醉酒躺在街头,雨水打湿了衣服,妻子用板车拉回家valenti电陶炉怎样valenti电陶炉产品介绍详解趣味桥和真人CS欧洲战国时代的开端分化与多中心的形成我们还能快乐的玩耍了吗我吃你大爷

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找