Spring三大功能之-声明式事务

工程结构:

  • dao层
package com.example.dao.impl;

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

@Repository
public class StudentDaoImpl {

    // jdbcTemplate 也从 ioc 容器中获取,在配置类中配置该bean,在整体都加入ioc容器中,他们一起都是透明可见的
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Transactional
    public void update() {
        String sql = "update students set age=18 where id = ?";
        jdbcTemplate.update(sql, 1);
        // float result = 1 / 0;
        String sql2 = "update students set class = '复读生' where id = ?";
        jdbcTemplate.update(sql2, 1);
    }
}

  • service层
package com.example.service.impl;

import com.example.dao.impl.StudentDaoImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class StudentServiceImpl {

    @Autowired
    private StudentDaoImpl studentDao;

    public void updateInfo() {
        studentDao.update();
    }
}
  • 配置类
package com.example.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;

@Configuration // 声明配置类
@PropertySource(value = {"classpath:jdbc.properties"}) // 加载外部配置文件
@ComponentScan(value = {"com.example"}) // ioc 容器注解扫描,实现注入
// TODO Spring tx 声明式事务实现步骤
@EnableTransactionManagement // TODO 2、开启 spring-tx 声明式事务注解
public class JavaConfig {

    // 从配置文件中获取成员属性
    @Value("${atguigu.url}")
    private String url;

    @Value("${atguigu.driver}")
    private String driver;

    @Value("${atguigu.username}")
    private String username;

    @Value("${atguigu.password}")
    private String password;

    // 数据库连接池对象注入 ioc
    @Bean
    public DataSource dataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(url);
        dataSource.setDriverClassName(driver);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        return dataSource;
    }

    // 操刀 连接池的技术,注入 ioc,ioc容器实例化后会自动从容器中获取参数中DataSource的实例对象赋值给形参dataSource
    @Bean
    public JdbcTemplate jdbcTemplate() {
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        // jdbcTemplate.setDataSource(dataSource);
        // 这里使用另一种方式:调用ioc容器中其它的 bean
        jdbcTemplate.setDataSource(dataSource());
        return jdbcTemplate;
    }

    // spring-tx 声明式事务实现,JdbcTemplate 和 Mybatis 都可以使用 DataSourceTransactionManager 实现
    // TODO Spring tx 声明式事务实现步骤
    // TODO 1、将 DataSourceTransactionManager 注入ioc中
    @Bean
    public TransactionManager transactionManager(DataSource dataSource) {
        DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
        // 设置想要被 DataSourceTransactionManager 事务管理的 JDBC DataSource 连接池对象
        dataSourceTransactionManager.setDataSource(dataSource);
        // 就会将 dataSourceTransactionManager 事务管理对象注入到 ioc 容器中,然后就可以在需要事务的方法、类上面通过事务注解实现控制
        return dataSourceTransactionManager;
    }
}

  • 测试类
package com.example;

import com.example.config.JavaConfig;
import com.example.service.impl.StudentServiceImpl;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;

/**
 * Spring声明式事务测试
 */
@SpringJUnitConfig(value = {JavaConfig.class}) // 自动创建Spring IOC容器
public class SpringTxTest {
    // 从ioc容器中获取service
    @Autowired
    @Qualifier(value = "studentServiceImpl") // 其实,这里可以不用指定,因为 StudentServiceImpl 在ioc容器中的实例只有,会自动装配上
    private StudentServiceImpl studentService;

    @Test
    public void test() {
        studentService.updateInfo();
    }
}

通过测试结果可以看到,update() 方法中的两条sql语句的执行结果具有统一性。

posted @ 2023-10-30 16:45  LoremMoon  阅读(4)  评论(0编辑  收藏  举报