黑马程序员技术交流社区

标题: 关于IDEA执行jdk代理debug结果与运行结果不一致问题 [打印本页]

作者: superhi    时间: 2018-10-18 18:55
标题: 关于IDEA执行jdk代理debug结果与运行结果不一致问题
本帖最后由 superhi 于 2018-10-19 09:09 编辑

最近学习了ssm框架,在学习spring的时候,有讲到jdk代理,然后做了一个银行转账的案例,在该案例里面使用了jdk代理对转账的功能进行事务控制,即转账人账户扣钱和收账人账户加钱需要同时成功或者同时失败。该案例我使用的是纯注解方式来做的,我在debug时发现,单步调试的结果和直接运行的结果不一致,单步调试的时候,会发现转账功能在出现异常的情况下,回滚会失败。
测试类:


动态代理类:


被代理类:


直接运行时,程序是正常的,会进行回滚,即转账人不会扣钱,收账人不会收到钱。但当断点打在动态代理类上,进行单步调试则不行,然后我在动态代理类上添加了打印方法名称的语句,即打印被代理的方法名称,然后进行单步调试,会发现控制台不止打印了transfer方法, 还打印了toString方法。
控制台输出(debug):

控制台输出(run):


原因:代理类会代理AccountServiceImpl类的所有方法包括toString方法,单步调试时IDEA会调用被代理类的toString方法。但是为什么调用了toString会导致transfer异常时回滚失败呢?是因为该案例的事务控制是通过使用TheadLoacl对象把Connection和当前线程绑定,从而使一个线程中只能有一个能控制事务的连接对象。而toString方法在transfer方法被调用之前调用的,在transfer方法出异常回滚之前,已经执行了transcationManager.release()方法,将连接释放并且与线程解绑,这就导致transfer方法出异常进行回滚时会失败,因为事务开始时使用的连接和回滚时使用的连接不是同一个连接,于是导致回滚失败,即转账人的钱扣了,但是收账人并没有收到钱。

作者: congge123    时间: 2018-10-21 14:55
厉害了,大神
作者: darrelluo    时间: 2018-10-24 09:31
大神
作者: 一只废狗    时间: 2018-10-24 11:03
加油大神
作者: fanlixing    时间: 2018-10-24 15:08
加油,加油
作者: 刺眼的小裤衩666    时间: 2018-10-24 15:50
大神加油
作者: 陌生人!    时间: 2018-10-24 16:10
加油   努力   做更好的自己
作者: 美人儿    时间: 2018-10-24 16:25
大神




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2