Spring源码一.(5)事务理解

博客探讨了Spring事务管理中@Transactional注解的使用,强调了开启事务支持、配置类@Configuration的重要性。通过一个实例展示了当手动抛出异常但未指定rollbackFor属性时,事务失效导致数据入库。同时指出,若@Configuration缺失,dataSource非单例也会导致事务失效,因为连接对象不一致。
摘要由CSDN通过智能技术生成

一.入门知识点

@Transactional注解: 会产生代理对象,实现功能的改变和增强

  Object target : 目标对象

  Proxy :代理对象

  如果是CGLIB的动态代理,会在代理对象中 存在一个目标对象的属性例如

  Class Proxy{

          Object target;

  }

  在前置执行后,会调用target对象的XX方法,执行对应逻辑,后面再执行后置动作

 二.在配置类上要开启事务支持功能 

 @EnableTransactionManagement

三.对应代码实现

package com.transaction.wang;

import org.apache.ibatis.datasource.pooled.PooledDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;

@ComponentScan("com.transaction.wang")
@EnableTransactionManagement
@Configuration
public class TransactionConfig {
    @Bean
    public PlatformTransactionManager platformTransactionManager(){
        DataSourceTransactionManager manager = new DataSourceTransactionManager();
        manager.setDataSource(dataSource());
        return manager;
    }

    @Bean
    public JdbcTemplate jdbcTemplate(){
        return new JdbcTemplate(dataSource());
    }

    @Bean
    public DataSource dataSource(){
        //DataSource ds = new PooledDataSource("com.mysql.jdbc.Driver","jdbc:mysql://localhost:3306/wang_learn","root","root");
        DriverManagerDataSource dds = new DriverManagerDataSource
                ("jdbc:mysql://localhost:3306/wang_learn","root","root");
        return dds;
    }
}

package com.transaction.wang;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class TestTx {

    public static void main(String[] args) throws Exception{
        System.out.println("args = " + args);

        AnnotationConfigApplicationContext
                app = new AnnotationConfigApplicationContext(TransactionConfig.class);

        System.out.println("app = " + app);

        DbDao bean = app.getBean(DbDao.class);

        bean.insertOneData();

    }
}

package com.transaction.wang;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

@Component
public class DbDao {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    // rollbackFor=Exception.class
    @Transactional(rollbackFor=Exception.class)
    public void insertOneData() throws Exception {
        String sql = "INSERT INTO t_wang_tx(my_id,my_var,my_int) VALUES(300,'qqq',2)";
        jdbcTemplate.execute(sql);
        throw new Exception("事务异常了");
        //throw new NullPointerException();
    }
}

执行结果图:

可以观察到库中并没有数据进入.

四:小结

在模拟过程,遇到了事务失效的问题,就是手动抛出异常后,数据任然入库了,在尝试后发现是@Transaction注解上没有加上rollbackFor = Exception.class导致!

此外,如果去掉配置类上的@Configuration注解,一样会导致事务失效,这个是由于dataSource对象不是同一个(非单例),导致事务对应的connection对象 和 执行sql的jdbcTeplate里面的connection对象不是同一个导致!这里结合spring学习第三篇一起理解!spring源码一.(3)@Configuration注解理解_ccwangwang的博客-CSDN博客

 

    

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值