跳转至

Spring 事务多 SQL 是一个连接吗

一、结论

一个连接。

二、为什么

事务要 ACID,多个连接就不是同一个事务了。

三、Spring 怎么保证

ThreadLocal

Spring 把连接绑到当前线程:

private static final ThreadLocal<Map<Object, Object>> resources = new ThreadLocal<>();

同一个线程,从 ThreadLocal 拿同一个连接。

四、流程

  1. 开启事务,从 DataSource 拿连接。
  2. 把连接放 ThreadLocal。
  3. 执行 SQL,从 ThreadLocal 拿连接。
  4. 所有 SQL 用同一个连接。
  5. 提交/回滚,清 ThreadLocal。

五、为什么不用 Map

Map 的话多线程不安全,而且不知道什么时候清。

ThreadLocal: - 线程私有。 - 线程结束自动清。 - 线程池注意要手动清。

六、注意

  • 跨线程事务失效。
  • 异步方法事务失效。

一句话

ThreadLocal 把连接绑到当前线程,保证一个事务一个连接。