select * from information_schema.innodb_trx;
不多解释,你只要知道这是查询当前数据库有哪些事务正在执行的语句就行。
你就注意看下面的动图,是不是第 27 行查询语句执行完成之后,查询事务的语句才能查出数据,说明事务这才真正的开启:
最后,我们把目光转移到这个方法的注释上:
写这么长一段注释,意思就是给你说,这个参数我们默认是 ture,原因就是在某些 JDBC 的驱动中,切换为自动提交是一个很重的操作。
那么在哪设置的为 true 呢?
没看到代码,我一般是不死心的。
所以,一起去看一眼。
setAutoCommit 这个方法有好几个实现类,我也不知道具体会走哪一个:
所以,我们可以在下面这个接口打上一个断点:
java.sql.Connection#setAutoCommit
然后重启程序,IDE 会自动帮你判断走那个实现类的:
可以看到,默认确实是 true。
等等,你不会真的以为我是想让你看这个 true 吧?
我是想让你知道这个调试技巧啊。
不知道有多少个小伙伴曾经问过我:这个接口实现类好多啊,我怎么知道在哪打断点啊?
我说:很简单啊,就在每个实现类的第一行代码打上断点就好了。
然后他说:别闹,我经常给你的文章一键三联。
我当时就被感动了,既然是这样的好读者,我当然把可以直接在接口上打断点的这个小技巧教给他啦。
好了,不扯远了。
再说一个小细节,这一小节就收尾。
你再去看这小节的开头,我直接说答案藏在这个方法里面:
org.springframework.jdbc.datasource.DataSourceTransactionManager#doBegin
直接把答案告诉你了,隐去了探索的过程。
但是这个东西,就像是数学公式推导一样,省略了一步,就会让人看起来一脸懵逼。
就像下面这个小耗子一样:
所以,我是怎么知道在这个地方打断点的呢?
答案就是调用栈。
先给大家看一下我的代码:
啥也先不管,上来就先在 26 行,方法入口处打上断点,跑起来:
诶,你看这个调用栈,我框起来的这个地方:
看这个名字,你就不好奇吗?
它简直就是在跳着脚,在喊你:点我,快,愣着干啥,你TM快点我啊。我这里有秘密!
然后,我就这样轻轻的一点,就到了这里:
org.springframework.transaction.interceptor.TransactionAspectSupport#invokeWithinTransaction
这里有个切面,可以理解为 try 里面就是在执行我们的业务代码逻辑:
而在 try 代码块,执行我们的业务代码之前,有这样的一行代码:
找到这里了,你就在这一行代码之前,再轻轻的打个断点,然后调试进去,就能找到这一小节开始的时候,说的这个方法: