声明式事务——事务回滚的实现

事务回滚:比如一个部门里面有很多成员,这两者分别保存在部门表和成员表里面,在删除某个部门的时候,假设我们默认删除对应的成员。但是在执行的时候可能会出现这种情况,我们先删除部门,再删除成员,但是部门删除成功了,删除成员的时候出异常了。这时候我们希望如果成员删除失败了,之前删除的部门也取消删除。这种场景就可以使用@Transactional事物回滚。

简单概括为,如果一个事务方法在执行时某一个方法出现异常,那么前所执行的所有该事务方法体内的方法都进行回滚,即失效、

实现事务回滚分三步:

第一步:

配置事务管理器来控制事务

注意:一定不要忘记将事务管理器加入进容器,且事务管理器必须管理数据源

    //事务管理器
    @Bean
    public PlatformTransactionManager transactionManager() throws PropertyVetoException {
        //事务管理器要管理数据源,这样他才能控制数据源里面的每一条链接
        return new DataSourceTransactionManager(dataSource());
    }

第二步:

使用**@Transactional注解:给方法上标注@Transactional表示当前方法是一个事务方法;Spring在执行这个方法的时候就会进行事务控制,如果这个方法正常进行,那么所有的方法都提交,如果在执行过程中出现异常,那么所有的方法都回滚。**

 @Transactional//表示当前是一个事务方法
    public  void insertUser(){
        userDao.insert();//数据库添加方法
        System.out.println("插入完成");
        int i=1/0;//此处会报错数学异常,因为这是一个事务方法,所以数据库添加方法也会进行回滚失效
    }

第三步:

使用@EnableTransactionManagement注解:开启基于注解的事务管理功能;

示例:

配置类:

@ComponentScan("com.tx")
@EnableTransactionManagement//开启基于注解的事务管理功能的注解
@Configuration//声明这是一个配置类
public class txConfig {
    //加载数据源
    @Bean
    public DataSource dataSource() throws PropertyVetoException {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setUser("root");
        dataSource.setPassword("123456");
        dataSource.setDriverClass("com.mysql.jdbc.Driver");
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");
        return dataSource;
    }
    //JdbcTemplate可以简化增删改查的操作
    @Bean
    public JdbcTemplate jdbcTemplate() throws PropertyVetoException {
        //JdbcTemplate需要从数据源里面获取链接,所以需要将数据源作为参数
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource());
        return jdbcTemplate;
    }
    //注册事务管理器
    @Bean
    public PlatformTransactionManager transactionManager() throws PropertyVetoException {
        //事务管理器要管理数据源,这样他才能控制数据源里面的每一条链接
        return new DataSourceTransactionManager(dataSource());
    }
}

业务逻辑层(dao):

@Repository
public class UserDao {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    public void insert(){
        //数据库插入语句
        String sql="INSERT INTO person(name,age) VALUES(?,?)";
        //获取一个随机数作为数据库name中的字段
        String substring = UUID.randomUUID().toString().substring(0, 5);
        jdbcTemplate.update(sql,substring,20);
    }
}

服务层(Service):

@Service
public class UserService {
    @Autowired
    private UserDao userDao;

    @Transactional//表示当前是一个事务方法
    public  void insertUser(){
        userDao.insert();
        System.out.println("插入完成");
        int i=1/0;
    }
}

测试类:

public class test_TX {
    @Test
    public void  test1(){
        //1、创建IOC容器
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(txConfig.class);
        UserService userService = applicationContext.getBean(UserService.class);
        userService.insertUser();
        applicationContext.close();
    }
}

成功效果:
在这里插入图片描述
当我们把Transactional注解关闭,测试失败,效果如下:

@Service
public class UserService {
    @Autowired
    private UserDao userDao;

    //@Transactional//表示当前是一个事务方法
    public  void insertUser(){
        userDao.insert();
        System.out.println("插入完成");
        int i=1/0;
    }
}

在这里插入图片描述
刚刚开始学Spring注解的知识,只是为了记录。有不对的地方,欢迎指出!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值