44.Spring事务底层实现源码解析

@EnableTransactionManagement

使用@EnableTransactionManagement注解来开启Spring事务

功能就是向Spring容器中添加了两个Bean:

  1. AutoProxyRegistrar
  2. ProxyTransactionManagementConfiguration,又定义了另外三个bean
    1. BeanFactoryTransactionAttributeSourceAdvisor:一个Advisor
    2. AnnotationTransactionAttributeSource:相当于BeanFactoryTransactionAttributeSourceAdvisor中的Pointcut,判断某个类/方法上是否存在@Transactional注解
    3. TransactionInterceptor:相当于BeanFactoryTransactionAttributeSourceAdvisor中的Advice
Spring事务基本执行原理

判断当前当前Bean对象是否和BeanFactoryTransactionAttributeSourceAdvisor匹配,匹配逻辑为判断该Bean的类上是否存在@Transactional注解,如果匹配则执行该Advisor中的TransactionInterceptor的invoke()方法,执行基本流程为:

  1. 利用所配置的PlatformTransactionManager事务管理器新建一个数据库连接

  2. 修改数据库连接的autocommit为false

  3. 执行MethodInvocation.proceed()方法,简单理解就是执行业务方法,其中就会执行sql

  4. 如果没有抛异常,则提交

  5. 如果抛了异常,则回滚

Spring事务传播机制

以非事务方式运行,Spring事务管理器不会去建立数据库连接,执行sql时,由Mybatis或JdbcTemplate自己来建立数据库连接来执行sql。

默认情况下传播机制为REQUIRED,表示当前如果没有事务则新建一个事务,如果有事务则在当前事务中执行。

Spring事务有可能会提交,回滚、挂起、恢复,所以Spring事务提供了一种机制,可以让程序员来监听当前Spring事务所处于的状态。在org.springframework.transaction.support.AbstractPlatformTransactionManager#processCommit中进行调用。

@Service
public class AskService {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private AskService askService;

    private Timestamp now = new Timestamp(System.currentTimeMillis());
    @Transactional(timeout = 1)
    public void test(){
        //打印事务名称
        System.out.println(TransactionSynchronizationManager.getCurrentTransactionName());
        String sql = "INSERT INTO `t_emp` (`name`,`age`,`sex`,`created_at`) VALUES (?,?,?,?)";
        //自定义
        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
            @Override
            public void suspend() {
                System.out.println("test被挂起了");
                TransactionSynchronization.super.suspend();
            }

            @Override
            public void resume() {
                System.out.println("test被恢复了");
                TransactionSynchronization.super.resume();
            }

            @Override
            public void beforeCommit(boolean readOnly) {
                System.out.println("test准备要提交了");
                TransactionSynchronization.super.beforeCommit(readOnly);
            }

            @Override
            public void beforeCompletion() {
                System.out.println("test准备要提交或回滚了");
                TransactionSynchronization.super.beforeCompletion();
            }

            @Override
            public void afterCommit() {
                System.out.println("test提交成功了");
                TransactionSynchronization.super.afterCommit();
            }

            @Override
            public void afterCompletion(int status) {
                System.out.println("test提交或回滚成功了");
                TransactionSynchronization.super.afterCompletion(status);
            }
        });
        try {
            int i = jdbcTemplate.update(sql, "王重阳", 55, "男", now);
            //事务超时
//            Thread.sleep(2000);
            System.out.println("受影响行数:" + i);
//        throw new NullPointerException();
            askService.insert();
        } catch (Exception e) {
            e.printStackTrace();
            //事务强制回滚
//        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        throw new NullPointerException();
    }
//    @Transactional(timeout = 5000, propagation = Propagation.REQUIRED)
    @Transactional(timeout = 5000, propagation = Propagation.REQUIRES_NEW)
//    @Transactional(timeout = 5000, propagation = Propagation.NOT_SUPPORTED)
    public void insert(){
        System.out.println(TransactionSynchronizationManager.getCurrentTransactionName());
        String sql = "INSERT INTO `t_emp` (`name`,`age`,`sex`,`created_at`) VALUES (?,?,?,?)";
        int i = jdbcTemplate.update(sql, "小龙女", 20, "未知", now);
        System.out.println("受影响行数:" + i);
//        throw new NullPointerException();
    }

}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值