zoukankan      html  css  js  c++  java
  • 【Spring】Spring事务管理实现方式(十五)

    一、Spring事务管理实现方式

      按是否通过编程分为声明式事务和编程式事务

    • 声明式事务:

      声明式事务:通过AOP(面向切面)方式在方法前使用编程式事务的方法开启事务,在方法后提交或回滚。用配置文件的方法或@(如:@Transactional)控制事务。

      通过XML配置或者注解实现。

    • 编程式事务:

      手动开启、提交、回滚事务。

      通过编程代码在业务逻辑时需要时自行实现,粒度更小。

    二、声明式事务

      本例通过@Transactional注解的方式实现声明式事务

    1、ITargetService接口

    1 public interface ITargetService {
    2 
    3     void update();
    4 
    5 }

    2、TargetService实现类

     1 @Service
     2 public class TargetService implements ITargetService {
     3 
     4     @Autowired
     5     JdbcTemplate jdbcTemplate;
     6 
     7     @Transactional
     8     @Override
     9     public void update(){
    10         
    11         String sql="update user set name = '王四' where id = 3";
    12         int update = jdbcTemplate.update(sql);
    13     }
    14 }

    3、配置类,主要是注入了数据源、JDBCTemplate 和 事务管理器

     1 @Configuration
     2 // 开启事务管理
     3 @EnableTransactionManagement
     4 @ComponentScan("com.test.tx.service")
     5 public class MainConfig {
     6 
     7     // 数据源
     8     @Bean("druidDataSource")
     9     public DataSource druidDataSource(){
    10         System.out.println("初始化数据源 DruidDataSource ");
    11 
    12         String url="jdbc:mysql://192.168.0.1:3306/test?allowPublicKeyRetrieval=true&useSSL=true";
    13         String username = "root";
    14         String password = "123456";
    15         String driverClassName = "com.mysql.cj.jdbc.Driver";
    16 
    17         DruidDataSource druidDataSource = new DruidDataSource();
    18         druidDataSource.setUsername(username);
    19         druidDataSource.setPassword(password);
    20         druidDataSource.setUrl(url);
    21         druidDataSource.setDriverClassName(driverClassName);
    22 
    23         return druidDataSource;
    24     }
    25 
    26     // jdbcTemplate
    27     @Bean
    28     public JdbcTemplate jdbcTemplate(){
    29         System.out.println("初始化 JdbcTemplate ");
    30 
    31         JdbcTemplate jdbcTemplate = new JdbcTemplate(druidDataSource());
    32         return jdbcTemplate;
    33     }
    34 
    35     // 事物管理器
    36     @Bean
    37     public TransactionManager transactionManager(){
    38         return new DataSourceTransactionManager(druidDataSource());
    39     }
    40 }

    4、主方法调用

    1 public class MainStarter {
    2     public static void main(String[] args) {
    3         AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);
    4 
    5         ITargetService targetService = context.getBean(ITargetService.class);
    6         targetService.update();
    7     }
    8 }

    三、编程式事务

    1、方法一:使用DefaultTransactionDefinition,定义一个事务,获取事务状态TransactionStatus,使用 PlatformTransactionManager 平台事务对象来管理

      新建一个TestService

     1 @Service
     2 public class TestService {
     3 
     4     @Autowired
     5     private TransactionManager transactionManager;
     6 
     7     @Autowired
     8     private JdbcTemplate jdbcTemplate;
     9 
    10     public void test1() {
    11         PlatformTransactionManager txManager = (PlatformTransactionManager) this.transactionManager;
    12         // 定义事务隔离级别,传播行为,
    13         DefaultTransactionDefinition def = new DefaultTransactionDefinition();
    14         def.setIsolationLevel(TransactionDefinition.ISOLATION_REPEATABLE_READ);
    15         def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
    16         // 事务状态类,通过PlatformTransactionManager的getTransaction方法根据事务定义获取;
    17         // 获取事务状态后,Spring根据传播行为来决定如何开启事务
    18         TransactionStatus status = txManager.getTransaction(def);
    19         try {
    20             jdbcTemplate.update("update user set name = '王五' where id = 3");
    21             int n = 1/0;
    22             // 提交status中绑定的事务
    23             txManager.commit(status);
    24         } catch (RuntimeException e) {
    25             // 回滚status中绑定的事务
    26             txManager.rollback(status);
    27         }
    28     }
    29 }

    2、方式二:使用TransactionTemplate,该类继承了接口DefaultTransactionDefinition,用于简化事务管理,事务管理由模板类定义,主要是通过TransactionCallback回调接口或TransactionCallbackWithoutResult回调接口指定,通过调用模板类的参数类型为TransactionCallback或TransactionCallbackWithoutResult的execute方法来自动享受事务管理。

    TransactionTemplate模板类使用的回调接口:

    • TransactionCallback:通过实现该接口的“T doInTransaction(TransactionStatus status) ”方法来定义需要事务管理的操作代码;

    • TransactionCallbackWithoutResult:继承TransactionCallback接口,提供“void doInTransactionWithoutResult(TransactionStatus status)”便利接口用于方便那些不需要返回值的事务操作代码。

      1)配置类中添加TransactionTemplate 事务模版的注册

     1 // 事务模版
     2 @Bean
     3 public TransactionTemplate transactionTemplate(){
     4     // DataSourceTransactionManager 实现了 PlatformTransactionManager 接口
     5     TransactionTemplate template = new TransactionTemplate((PlatformTransactionManager)transactionManager() );
     6     // 设置隔离级别,重复读取
     7     template.setIsolationLevel(TransactionDefinition.ISOLATION_REPEATABLE_READ);
     8     // 设置传播行为,重复读取
     9     template.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
    10     return template;
    11 }    

      2)使用事务模版 transactionTemplate

     1 public void test2() {
     2 
     3         transactionTemplate.execute(new TransactionCallbackWithoutResult() {
     4                              // 在事务中执行,且没有结果返回
     5                              @Override
     6                              protected void doInTransactionWithoutResult(TransactionStatus status) {
     7                                  // 报异常,自动回滚,TransactionTemplate自动管理事务
     8                                  jdbcTemplate.update("update user set name = '王五' where id = 3");
     9                                  throw new RuntimeException();
    10                              }
    11                          }
    12         );
    13 
    14         // 有结果返回的执行
    15 //        Object result = transactionTemplate.execute(new TransactionCallback<Object>() {
    16 //            // 在事务中执行
    17 //            @Override
    18 //            public Object doInTransaction(TransactionStatus status) {
    19 //                return null;
    20 //            }
    21 //        });
    22     }


    参考:https://blog.csdn.net/liaohaojian/article/details/70139151

  • 相关阅读:
    OAuth2.0认证和授权原理
    APNs详细使用步骤
    解决IDEA因分配内存而引起的卡顿
    JAVA 第二周学习总结
    JAVA 第一周学习总结
    Mac OS 上配置java开发环境
    【DP】【单调队列】洛谷 P2216 [HAOI2007]理想的正方形 题解
    【DP】【构造】NOIp模拟题 演讲 题解
    【2-SAT】【并查集】NOIp模拟题 植树方案 题解
    【字符串】【hash】【倍增】洛谷 P3502 [POI2010]CHO-Hamsters 题解
  • 原文地址:https://www.cnblogs.com/h--d/p/14692094.html
Copyright © 2011-2022 走看看