H__D  

一、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

 

posted on 2021-04-23 00:16  H__D  阅读(235)  评论(0编辑  收藏  举报