如何解决由于错误使用SpringBoot导致的问题
如何解决由于错误使用SpringBoot导致的问题,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。
在某一天,有个业务线同鞋找到笔者,说,他们的一个应用事务失败了没有回滚。已经与DBA对过数据,且自行查看代码中的事务使用方式也没有问题。后在笔者的多番劳作中,找到了问题的原因。说起来引起该故障的原因很简单,但查询的新路历程值得说道说道。
如果业务童鞋说的正确的话。事务配置成功、且有效。那这个问题就表现的很诡异,或者说几乎不可能。所以笔者第一个怀疑的对象是:
1. 事务配置错误
通过简单跟踪、测试,敲定事务确实没啥问题。。此时脑海中1万个问号??
2. 后续周围的同事,都对该问题比较感兴趣,一一提出假设,最终都被一一排除。
无奈之下,笔者只好一点点跟踪代码,虽说,Idea的debug模式已经很好用,但一通操作下来,还有有些难度。
好在黄天不负苦心人,灵光乍现,猜测:会不会是执行的数据源并没有事务。与应用启动的时,创建的数据源并不是同一个。
抱着试试看的态度,我把断点放在了启动时,数据源bean生成的位置。最终发现,果然启动生成的bean与运行中的bean并不是同一个。。汗颜!!!
下面是原因说明:
根据业务代码,产生该问题的条件
启动过程中,吃掉启动异常,导致容器无法因为异常 而 终止掉
启动过程中,抛出异常
原因分析
spring容器启动之后,初始化bean: DataSource (A)
mybatis缓存DataSource(A)
容器启动异常,spring清除所有已缓存的bean信息。
由于启动类中,吃掉了容器启动异常。容器未挂掉
此时dubbo请求进来之后,由于spring中的所有bean信息都被清除,因此。容器重新初始化bean。此时生成DataSource (B)、事务管理器
事务方法执行前,事务管理器,对DataSource (B) 设置setAutoCommit=0。并将DataSource与事务关系存放到map(C)中
myabtis在执行时会从 第6步的map中,根据DataSource(A) 获取事务信息。在这种情况下,是无法获取到的。导致执行sql执行的采用的是DataSource(A)。而这个DataSource(A)从未设置setAutoCommit=0。导致事务无法回滚
看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注行业资讯频道,感谢您对的支持。