应用办公生活信息教育商业
投稿投诉
商业财经
汽车智能
教育国际
房产环球
信息数码
热点科技
生活手机
晨报新闻
办公软件
科学动态
应用生物
体育时事

一篇让你学会11个Spring失效场景

  其实关于spring事务失效的场景,网络上文章介绍的不少,参差不齐。这里只分享下自己的见解,时长大概10分钟左右,先上个图介绍下。
  1。访问权限问题
  事务方法需要定义public,非public方法事务会失效。事务拦截器TransactionalInterceptor会在执行方法前进行拦截,通过动态代理方式如果是cglib就是intercept方法或者jdk的invoke方法间接调用AbstractFallbackTransactionAttributeSource类的getTransactionAttribute方法获取配置信息,附上源码图:
  进一步的跟踪getTransactionAttribute方法,我们就能看到,spring对于非public修饰的方式,返回的事务对象是null,其中allowPublicMethodsOnly返回的是一个布尔false。
  2。方法被final修饰
  事务底层使用了aop,那么也就是说通过jdk或者是cglib生成代理类,在代理类中实现的事务的功能,如果说方法是final修饰的了,那么就会导致代理类中无法重写该方法,从而导致添加事务失败。同样的如果是static的修饰的话也是无法通过动态代理变成事务方法。3。方法内部调用
  简单来说就是一个方法内部调用另一个方法,但是另一个方式是有事务的,这样也会导致事务失效,因为这个调用的是this对象的方法,而不是另一个方法持有的对象,可以这里理解。
  如果想要在方法内部调用另一个方法也有事务的话,就需要新建一个service对象持有。ServicepublicclassTmTrimServicebackImpl{publicvoidgetById(Longid){TmTrimServiceliImpl。getTrimById(id);}}ServicepublicclassTmTrimServiceliImpl{Transactional(rollbackForException。class)publicvoidgetTrimById(Longid){TmTrimVOtmTrimVOnewTmTrimVO();}}
  这样,通过新建一个service方法,将事务添加到新建的service方法里就可以了。说到这里可能小伙伴觉得这样有点麻烦,那么是否有没有其他的方式不新建一个方法呢,答案是可以的,就是注入自己,利用了springioc内部的三级缓存的机制,这里注入自己就很好的保证了也不会出现循环依赖:ServicepublicclassTmTrimServicebackImpl{AutowiredprivateTmTrimServicebackImpltmTrimServicebackImpl;publicvoidgetById(Longid){tmTrimServicebackImpl。getTrimById(id);}Transactional(rollbackForException。class)publicvoidgetTrimById(Longid){TmTrimVOtmTrimVOnewTmTrimVO();}}
  其实到了这一步,还是发现有点不太雅观,并不是说上面代码有什么问题只是觉得,可以让上面代码更加好看一点,那么有没有呢,答案是有的,是什么呢?这就不得不佩服spring强大完善的支持,那就是AopContext。currentProxy(),这个就是创建代理类,在方法调调用前后切入,这个代理类对象是保存在ThreadLocal中的,所以通过这个代理类对象调用事务方法就能生效了。ServicepublicclassTmTrimServicebackImpl{publicvoidgetById(Longid){((TmTrimServicebackImpl)AopContext。currentProxy())。getTrimById(id);}Transactional(rollbackForException。class)publicvoidgetTrimById(Longid){TmTrimVOtmTrimVOnewTmTrimVO();}}
  这样看来,代码是不是就优雅多了,哈哈!!!4。未被spring事务管理
  这里需要明确一个前提,就是使用spring事务的前提,就是对象要被spring管理就需要创建bean实例,在开发中,我们都是通过Controller,Service,Component,Repository等注解自动的实现依赖注入实例化的功能,但假如说在相应的控制层,业务层,数据层忘记加相应的注解,那么也是会失效的。因为没有交给spring管理,例如:
  5。多线程调用
  回想起前几年配置事务管理器时,都会有这样的一段配置:
  通过这一段配置也可以知道,其实spring事务就是通过数据库连接事务多线程连接会导致持有的connetion不是同一个,从网上找了一张图,通过这张图进一步理解:
  接着附上伪代码结合上面的图进一步理解:Slf4jServicepublicclassUserService{AutowiredprivateUserMapperuserMapper;AutowiredprivateRoleServiceroleService;Transactionalpublicvoidadd(UserModeluserModel)throwsException{userMapper。insertUser(userModel);newThread((){roleService。doOtherThing();})。start();}}ServicepublicclassRoleService{TransactionalpublicvoiddoOtherThing(){System。out。println(保存role表数据);}}
  事务add方法中调用了另一个事务doOtherThing,但是事务方法是在另一个线程中调用的,这样就会导致两个方法不在同一个线程中,获取到的数据库链接不一样,是两个不同的事务,一旦doOtherThing发生异常,add方法也是不可能发生回滚的。这里需要解释以下什么是同一个事务,也就是说只有拥有同一个数据库连接才能同时提交和回滚。如果在不同的线程,拿到的数据库连接肯定是不一样的,所以是不同的事务。6。多线程调用
  这个就没什么好讲的了,也就是innodb和myisam引擎的不同,5版本以前默认是myisam引擎,这个引擎是不支持事务的,5版本以后的innodb是支持事务的。7。未开启事务
  这个其实可能也是比较容易忽略的,因为我们印象里好像没怎么配置过怎么开启事务,也确实是这样哈,为什么?其实原因很简单,springboot项目通过DataSourceTransactionManagerAutoConfiguration这个类已经默默的为我们开启了事务。
  这个类会加载spring。datasource这个配置文件从而启动事务,如果是非springboot项目就需要自己手动在xml文件中配置事务管理器。beanclassorg。springframework。jdbc。datasource。DataSourceTransactionManageridtransactionManagerpropertynamedataSourcerefdataSourcepropertybean
  类似这样的从而开启事务。8。错误的传播特性
  在使用Transactional注解时,是可以指定propagation参数的,该参数是用来指定事务的传播特性,其中只有required,requiresnew,nested这三种才会创建新事务:ServicepublicclassUserService{Transactional(propagationPropagation。NEVER)publicvoidadd(UserModeluserModel){saveData(userModel);updateData(userModel);}}
  像上面的Propagation。NEVER这种类型的传播特性不支持事务,如果有事务则会抛异常。9。自己吞了异常Slf4jServicepublicclassUserService{Transactionalpublicvoidadd(UserModeluserModel){try{saveData(userModel);updateData(userModel);}catch(Exceptione){log。error(e。getMessage(),e);}}}
  像这种手动try。。。catch了异常,又没有手动抛出,那么sring就会认为程序是异常的就不会回滚了。10。手动抛了别的异常Slf4jServicepublicclassUserService{Transactionalpublicvoidadd(UserModeluserModel)throwsException{try{saveData(userModel);updateData(userModel);}catch(Exceptione){log。error(e。getMessage(),e);thrownewException(e);}}}
  捕获了异常又抛出了exception异常,事务同样不会回滚,因为spring事务默认情况下只会回滚RuntimeException(运行时异常)和Error(错误),对于普通的Exception(非运行时异常),不会回滚,网上找了一张图:
  这里exception里除了分为运行时异常和非运行时异常(ioException)。
  1)让checked例外也回滚:
  在整个方法前加上Transactional(rollbackForException。class)
  2)让unchecked例外不回滚:
  Transactional(notRollbackForRunTimeException。class)
  3)不需要事务管理的(只查询的)方法:Transactional(propagationPropagation。NOTSUPPORTED)
  这里需要提及的一句是,如果是自定义了的异常,比如说我自定义了DALException异常,那么就应该是Transactional(notRollbackForDALException。class),一旦抛出的异常不属于DALException异常,那么事务也是不会生效的。11。嵌套事务回滚多了
  其实这个就有点像是js里的冒泡事件,可能我只是需要底部,结果外层窗口事件也触发了,联想到事务这里,那么也是一样的,嵌套多个可能只是想回滚对应的事务,就不用把其他事务也回滚了,这个可以通过try。。。catch来处理,将需要处理回滚的事务放这里面就不会把外层的也会滚了。
  原文链接:https:developer。51cto。comarticle703239。html?utmsourcetuicoolutmmediumreferral

西决前瞻库里如何破包夹是关键勇士如何防守东契奇?(注:作者是勇士记者AnthonySlater,文章内容不代表译者观点。)本赛季常规赛勇士队和独行侠队的最后一次交锋,在比赛的后期逐渐进入了紧张的状态。对位上的一些因素削……吃知了猴,对身体有什么影响,是好还是不好?说起夏天最常吃到的食物是什么?想必大家,第一眼想到的就是知了猴知了猴每个地区的称呼都大不相同,有的地区是金蝉有的地区是知了牛反正每个地区的叫法都不一样,但是它的吃法却都是……这个止麻的中成药,帮你缓解手脚麻木,腰腿酸痛!远离风湿骨病今天这篇文章,给大家介绍一个治疗风湿麻木的中成药。风湿带来的手脚麻木在中医里属于痹症的范畴,古书里记载为血痹。痹症又通谐音字闭症,字面意思就是闭塞,不通了,所以对照……可喜可贺!篮网马刺3人交易签约完成,杜兰特替身来了目前,一年一度的NBA交易市场正在火热进行中,参赛各队都在积极备战这场没有硝烟的抢人大战积极备战中,力争帮助球队在今夏完成阵容的升级补强,以在新赛季拿到更多场次的胜利。吸引了数……VR与文旅的碰撞,让旅行说走就走生活不只有眼前的苟且,还有诗和远方。在如今这个快节奏的社会里,每个人或多或少都有一个提上包,来一场说走就走的旅行梦。但说实话,这很难。节假日旅行,大概率会碰上……iPhone14系列的传闻越来越多,iPhone13沦为白菜如今网上关于iPhone14系列的传闻越来越多,不出意外的话,代工厂已经开始加班加点生产了。其实iPhone14系列之所以备受期待,主要是因为这款机型是近几年来升级幅度最大。特……动力和能效同步提升,雷神开启混动新时代哪种电动化动力类型会彻底取代纯燃油?目前行业内还没有一个百分百确切的说法。纯电动车虽然在前期发展迅速,但使用便利性上的局限使其无法成为市场的单一品类。随着产业技术的不断成……70!山东泰山河北队双双创造队史纪录,金钟夫发布会匆匆离场北京时间2022年8月15日,中超联赛迎来了第13轮的一场比赛,由河北队对阵山东泰山队。河北队在本赛季的战绩是1胜11负,成绩极为尴尬,已经基本锁定了一个降级名额。虽然成绩糟糕……小米平板5Pro12。4体验一块大屏是如何被小米榨干的?在雷军年度演讲上,小米一如既往的带来了许多秋季新品,赚足了米粉的眼球。这其中,就包括了小米平板家族的最新成员小米平板5Pro12。4。如果说小米平板5系列是小米平板沉寂三……90后宝妈爱美,哺乳期染发遭店主秒拒哺乳期染发对宝宝会有影响育儿事务所嗨,我是小清,点击上方关注,定期为你分享育儿干货。近日,刷到某音上在8月17日,在福建福州某理发店。一位哺乳期女子进店染发,店主得知情况后立刻拒绝,并劝其……从豪门名媛到败家女,20年后章小惠还是把人生这副牌打活了从出身豪门的富贵名媛,到众人嘲讽的拜金女,在世俗眼光看来,章小惠是从云端跌落泥土的例子。有人说她是锦衣玉食奢靡之娇女,有人说她靠美色败男人财产。时尚女王、奢侈品购物……腾讯下架QQ影音所有版本!网友别了,一起看片的老友来源都市现场综合中国基金报版权归原作者所有如有侵权请及时联系今日,腾讯下架QQ影音所有版本的消息冲上百度、微博热搜!记者从腾讯QQ影音官网了解到,该软件的PC……
与其抱怨生活,不如改变心态人活着总要经历一定的委屈。有委屈就容易产生埋怨。埋怨自己的怀才不遇,其实可能是努力还不够,才华还不够足够的出众、优秀;埋怨世态炎凉、人走茶凉,其实不过是你的私心太重……NASA开始检查刚从月球返回的猎户座飞船阅读文章之前,请点击关注,方便您回来查看内容,以及参与大家的互动,感谢您给予我码字动力!工程师们已经开始对阿特米斯1号太空舱进行检查,以了解它在月球旅行和重返大气层时的状……别老盯着人口规模红利了专家建议对50万以上存款征收利息税谈点个人看法:没有想到这样一条建议能够冲上头条热榜第一?背后还有什么政策逻辑,目前不得而知!我认为,这样的专家建议根本就不是什么好……江西这两县若合并,可能成吉安新市区吉安是江西的一个地级市,很多人可能对这个地名不是很熟悉,但说到井冈山是不是就很熟悉了。著名的井冈山就坐落在吉安境内,除了井冈山,市内还有武功山、青原山等一系列风景名胜,吉州窑等……云南省疾控中心提示春节期间儿童安全别放假!1月22日,云南省疾控中心发布最新提示,提醒大家,春节期间也要重视儿童安全问题,具体内容如下:云南疾控微信截图岁末年初,寒假和春节如期而至,同学们在休息调整、迎接新……你和母亲的关系,就是你和世界的关系和母亲的关系是一个人命运的雏形有的人拼命想成为母亲的样子,有的人却拼命不想成为母亲的样子。有的人一生都在感谢母亲带给自己人生的礼物,而有的人却一生都清晰的记得母亲带给自己……惊曝梅西泪别巴黎,冬窗转会纽卡斯尔,外媒太内涵了一条《突发!梅西泪别巴黎,即将加盟纽卡斯尔》的外文消息,今早成为热点。消息原文如下:在今天上午的发布会上,梅西强忍热泪宣布,他将离开巴黎圣日尔曼,转会前往纽卡斯尔。……最亮的恒星最明亮的恒星是天狼星。在北半球的冬季,出现在岁末最后几天,午夜正南方向的,那颗最明亮的星星就是天狼星,天狼星A位于人犬座星座,那是大犬座a星,也叫大犬座主星。那质量是太阳……山西,为什么如此重要?山西,为什么如此重要?有人说,山西不就有煤老板和暴发户吗这种看法真的是伤透了山西人的心事实上,很多人并不了解山西更不了解山西为何如此重要有人说,……日本推出免税商品自动售货机方便旅日游客A。日语新闻中文版随着疫情的日渐结束,日本各大产业都在期待旅游业回暖、旅日外国游客增加拉动国内销售。在此情况下,日本国内的一些机场和车站出现了一种服务于外国游客的储物柜式……中国两个城市明明很近,坐高铁却要12个小时,开车只需6个小时如今,交通设施越来越完善。人们出门时,可以通过各种交通方式满足自己的需求。一般来说,距离越近,时间越短。然而,中国有两个城市显然很近。坐高铁需要12个小时,开车只需要6个小时。……51单片机学习记认识单片机与51单片机单片机与51单片机什么是单片机?单片机又称单片微处理器,简称mcu。单片机是一种集成电路,是将中央处理器cpu,随机存储器RAM,只读存储器ROM,和多种IO口,包含中断……
友情链接:易事利快生活快传网聚热点七猫云快好知快百科中准网快好找文好找中准网快软网