Spring-AOP-事务管理

Spring的事务管理
  • 编程式事务管理 : 使用spring提供的TransactionTemplate来实现事务管理

  • 声明式事务管理 : 使用注解@Transactional ,利用AOP来实现事务管理

  • AOP的典型应用就是Spring的声明式事务管理.

  • 编程式事务管理:
    • 在TransactionTemplates中实现事务逻辑,事务本身的功能由TransactionTemplates完成.

    • 导入依赖:

      <!-- https://mvnrepository.com/artifact/org.springframework/spring-tx -->
          <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>5.2.1.RELEASE</version>
          </dependency>
          <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
          <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.2.1.RELEASE</version>
          </dependency>
      
    • 配置类:

      @Configuration  //设置为配置类
      @ComponentScan("com.li.spring")     //指定包扫描
      @PropertySource("database.properties")      //读取配置文件
      public class AopConfig {
      
          @Value("${jdbc.url}")
          private String url;
      
          @Value("${jdbc.driverClass}")
          private String driverClassName;
      
          @Value("${jdbc.userName}")
          private String userName;
      
          @Value("${jdbc.password}")
          private String password;
      
          //配置数据源=>提供connection pool
          @Bean
          public DruidDataSource druidDataSource(){
              //得到一个druid连接池对象
              DruidDataSource druidDataSource = new DruidDataSource();
              druidDataSource.setDriverClassName(driverClassName);
              druidDataSource.setUrl(url);
              druidDataSource.setUsername(userName);
              druidDataSource.setPassword(password);
              return druidDataSource;
          }
          
          @Bean
          public QueryRunner queryRunner(){
              return new QueryRunner(dataSourceProxy());
          }
      
          //数据源的代理,spring能够去控制事务的打开和提交等操作
          @Bean
          public TransactionAwareDataSourceProxy dataSourceProxy(){
              return new TransactionAwareDataSourceProxy(druidDataSource());
          }
      
          //事务管理器,管理事务,spring的统一的事务管理接口
          //PlatformTransactionManager接口里面有三个方法:
          //getTransaction 得到事务
          //commit 提交事务
          //rollback 回滚事务
          @Bean
          public PlatformTransactionManager transactionManager(){
              return new DataSourceTransactionManager(dataSourceProxy());
          }
      
          //统一的事务管理模板,只依赖PlatformTransactionManager接口,可以放其他的实现类
          @Bean
          public TransactionTemplate transactionTemplate(){
              return new TransactionTemplate(transactionManager());
          }
      
      //    事务模板 -> 事务管理器 ->数据源代理 ->数据源
      
      }
      
    • 业务层类:

      @Service("userService")
      public class UserServiceImpl implements UserService {
          @Autowired
          private QueryRunner queryRunner;
          @Autowired
          private TransactionTemplate transactionTemplate;
          @Override
          public void test() {
      
              transactionTemplate.execute(new TransactionCallbackWithoutResult() {
                  @Override
                  protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                      try {
                          queryRunner.update("insert into user values(default,?,?)","li1","99929");
                          if(transactionStatus!=null){
                              throw new RuntimeException("人工制造错误");
                          }
                          queryRunner.update("delete from user where user_id=7");
                          queryRunner.update("update user set user_name=? where user_id=?","superli",3);
                      } catch (SQLException e) {
                          e.printStackTrace();
                          //出现异常,设置回滚
                          transactionStatus.setRollbackOnly();
                      }
                  }
              });
          }
      }
      

      测试类:

      public class App {
          public static void main(String[] args) {
              AnnotationConfigApplicationContext acac = new AnnotationConfigApplicationContext(AopConfig.class);
              UserService userService = acac.getBean("userService", UserService.class);
              userService.test();
          }
      }
      

      结果:

      事务开启成功,数据都没有插入进去
      
  • 声明式事务管理:
    • 导入依赖,跟编程式事务管理导入相同的依赖

      <!-- https://mvnrepository.com/artifact/org.springframework/spring-tx -->
          <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>5.2.1.RELEASE</version>
          </dependency>
          <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
          <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.2.1.RELEASE</version>
          </dependency>
      

      配置类:与编程式事务管理不同是,声明式事务管理多了一个@EnableTransactionManagement的注解,用来开启事务,没有事务管理器和事务模板

      @Configuration  //设置为配置类
      @ComponentScan("com.li.spring")     //指定包扫描
      @PropertySource("database.properties")      //读取配置文件
      @EnableTransactionManagement    //启动事务管理
      public class AopConfig2 {
      
          @Value("${jdbc.url}")
          private String url;
      
          @Value("${jdbc.driverClass}")
          private String driverClassName;
      
          @Value("${jdbc.userName}")
          private String userName;
      
          @Value("${jdbc.password}")
          private String password;
      
          //配置数据源
          @Bean
          public DruidDataSource druidDataSource(){
              //得到一个druid连接池对象
              DruidDataSource druidDataSource = new DruidDataSource();
              druidDataSource.setDriverClassName(driverClassName);
              druidDataSource.setUrl(url);
              druidDataSource.setUsername(userName);
              druidDataSource.setPassword(password);
              return druidDataSource;
          }
      
          @Bean
          public QueryRunner queryRunner(){
              return new QueryRunner(dataSourceProxy());
          }
      
          //数据源的代理,Spring能够去控制事务的打开和提交等操作
          @Bean
          public TransactionAwareDataSourceProxy dataSourceProxy(){
              return new TransactionAwareDataSourceProxy(druidDataSource());
          }
      }
      

      业务类:与编程式事务管理不同是直接使用@Transactional注解启动事务,在抛出异常时会自动进行事务回滚,方便了很多

      @Service("userService")
      public class UserServiceImpl implements UserService {
          @Autowired
          private QueryRunner queryRunner;
          
          @Transactional
          public void test2() throws SQLException{
      
              queryRunner.update("insert into user values(default,?,?)","琪琪1","99929");
              if(queryRunner!=null){
                  throw new RuntimeException("人造错误");
              }
              queryRunner.update("delete from user where user_id=7");
              queryRunner.update("update user set user_name=? where user_id=?","superli",3);
      
          }
      }
      

      测试类:

      public class App {
          public static void main(String[] args) {
              AnnotationConfigApplicationContext acac = new AnnotationConfigApplicationContext(AopConfig2.class);
              UserService userService = acac.getBean("userService", UserService.class);
              try {
                  userService.test2();
              } catch (SQLException e) {
                  e.printStackTrace();
              }
          }
      }
      

      结果:

      当然,数据也没有插入进去啦
      
    • 声明式事务管理总结:

    • @Transactional

      • 配置类加@EnableTransactionManagement,启动spring的事务管理机制
      • 配置 datasource -> datasourceProxy -> PlatformTransactionManager + queryRunner
      • 需要的方法上加@Transactional,开启事务,遇到异常会进行事务回滚
      • AOP实现
        • 切入点: @Transactional所在的方法
        • 通知: Spring的事务管理
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值