美文网首页
spring 如何保证数据库事务在同一个连接下执行的

spring 如何保证数据库事务在同一个连接下执行的

作者: 秋天的铁工匠 | 来源:发表于2020-01-16 13:37 被阅读0次

ThreadLocal天生为解决相同变量的访问冲突问题, 所以这个对于spring的默认单例bean的多线程访问是一个完美的解决方案。spring也确实是用了ThreadLocal来处理多线程下相同变量并发的线程安全问题。

  • 要想实现jdbc事务, 就必须是在同一个连接对象中操作, 多个连接下事务就会不可控, 需要借助分布式事务完成。那spring 如何保证数据库事务在同一个连接下执行的呢?
  • DataSourceTransactionManager 是spring的数据源事务管理器, 它会在你调用getConnection()的时候从数据库连接池中获取一个connection, 然后将其与ThreadLocal绑定, 事务完成后解除绑定。这样就保证了事务在同一连接下完成。

事务开始阶段

public static void bindResource(Object key, Object value) throws IllegalStateException {
        Object actualKey = TransactionSynchronizationUtils.unwrapResourceIfNecessary(key);
        Assert.notNull(value, "Value must not be null");
        Map<Object, Object> map = resources.get();
        // set ThreadLocal Map if none found
        if (map == null) {
            map = new HashMap<>();
            resources.set(map);
        }
        Object oldValue = map.put(actualKey, value);
  • ThreadLocal存储的为DataSource生成的actualKey为key值和ConnectionHolder作为value值封装成的Map。
private static final ThreadLocal<Map<Object, Object>> resources =
            new NamedThreadLocal<>("Transactional resources");
  • 将 DBResource 和 ConnectionHolder分别作为KV存入 map
    Object oldValue = map.put(actualKey, value);

事务结束阶段

@Nullable
    private static Object doUnbindResource(Object actualKey) {
        Map<Object, Object> map = resources.get();
        if (map == null) {
            return null;
        }
        Object value = map.remove(actualKey);
        // Remove entire ThreadLocal if empty...
        if (map.isEmpty()) {
            resources.remove();
        }
  • 获取ThreadLocalMap
 resources.get();
  • 删除map 的Entry并移除
    Object value = map.remove(actualKey);
        // Remove entire ThreadLocal if empty...
        if (map.isEmpty()) {
            resources.remove();
        }

学习更多:
ThreadLocal 面试六连问,你能 Hold 住吗?
ThreadLocal-面试必问深度解析
Spring事务之如何保证同一个Connection对象

公众号"会讲历史的程序员",欢迎关注

相关文章

网友评论

      本文标题:spring 如何保证数据库事务在同一个连接下执行的

      本文链接:https://www.haomeiwen.com/subject/tpyfzctx.html