当Transactional碰到锁,有个大坑,要小心。 (3)

select * from information_schema.innodb_trx;

不多解释,你只要知道这是查询当前数据库有哪些事务正在执行的语句就行。

你就注意看下面的动图,是不是第 27 行查询语句执行完成之后,查询事务的语句才能查出数据,说明事务这才真正的开启:

当Transactional碰到锁,有个大坑,要小心。

最后,我们把目光转移到这个方法的注释上:

当Transactional碰到锁,有个大坑,要小心。

写这么长一段注释,意思就是给你说,这个参数我们默认是 ture,原因就是在某些 JDBC 的驱动中,切换为自动提交是一个很重的操作。

那么在哪设置的为 true 呢?

没看到代码,我一般是不死心的。

所以,一起去看一眼。

setAutoCommit 这个方法有好几个实现类,我也不知道具体会走哪一个:

当Transactional碰到锁,有个大坑,要小心。

所以,我们可以在下面这个接口打上一个断点:

java.sql.Connection#setAutoCommit

然后重启程序,IDE 会自动帮你判断走那个实现类的:

当Transactional碰到锁,有个大坑,要小心。

可以看到,默认确实是 true。

等等,你不会真的以为我是想让你看这个 true 吧?

我是想让你知道这个调试技巧啊。

不知道有多少个小伙伴曾经问过我:这个接口实现类好多啊,我怎么知道在哪打断点啊?

我说:很简单啊,就在每个实现类的第一行代码打上断点就好了。

然后他说:别闹,我经常给你的文章一键三联。

我当时就被感动了,既然是这样的好读者,我当然把可以直接在接口上打断点的这个小技巧教给他啦。

当Transactional碰到锁,有个大坑,要小心。

好了,不扯远了。

再说一个小细节,这一小节就收尾。

你再去看这小节的开头,我直接说答案藏在这个方法里面:

org.springframework.jdbc.datasource.DataSourceTransactionManager#doBegin

直接把答案告诉你了,隐去了探索的过程。

但是这个东西,就像是数学公式推导一样,省略了一步,就会让人看起来一脸懵逼。

就像下面这个小耗子一样:

当Transactional碰到锁,有个大坑,要小心。

所以,我是怎么知道在这个地方打断点的呢?

答案就是调用栈。

先给大家看一下我的代码:

当Transactional碰到锁,有个大坑,要小心。

啥也先不管,上来就先在 26 行,方法入口处打上断点,跑起来:

当Transactional碰到锁,有个大坑,要小心。

诶,你看这个调用栈,我框起来的这个地方:

当Transactional碰到锁,有个大坑,要小心。

看这个名字,你就不好奇吗?

它简直就是在跳着脚,在喊你:点我,快,愣着干啥,你TM快点我啊。我这里有秘密!

然后,我就这样轻轻的一点,就到了这里:

org.springframework.transaction.interceptor.TransactionAspectSupport#invokeWithinTransaction

这里有个切面,可以理解为 try 里面就是在执行我们的业务代码逻辑:

当Transactional碰到锁,有个大坑,要小心。

而在 try 代码块,执行我们的业务代码之前,有这样的一行代码:

当Transactional碰到锁,有个大坑,要小心。

找到这里了,你就在这一行代码之前,再轻轻的打个断点,然后调试进去,就能找到这一小节开始的时候,说的这个方法:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzdfsx.html