zoukankan      html  css  js  c++  java
  • Springboot使用PlatformTransactionManager接口的事务处理

    1、SpringBoot中可以使用PlatformTransactionManager接口来实现事务的统一控制,而进行控制的时候也可以采用注解或者AOP切面配置形式来完成,建议进行Aop切面进行事务管理,但是要写好注释,不然一些人后期找代码逻辑很容易看懵逼的。

    在业务层的方法上启用事务控制,可以加到方法上,也可以加到该业务类上,根据自己的需求来进行。

     1 package com.demo.service.impl;
     2 
     3 import java.util.List;
     4 
     5 import org.springframework.beans.factory.annotation.Autowired;
     6 import org.springframework.stereotype.Service;
     7 import org.springframework.transaction.annotation.Propagation;
     8 import org.springframework.transaction.annotation.Transactional;
     9 
    10 import com.demo.dao.UserDao;
    11 import com.demo.po.UserInfo;
    12 import com.demo.service.UserService;
    13 
    14 @Service
    15 public class UserServiceImpl implements UserService {
    16 
    17     @Autowired
    18     private UserDao userDao;
    19 
    20     /**
    21      * 在业务层的方法上启用事务管理
    22      */
    23     @Transactional(propagation = Propagation.REQUIRED, readOnly = true)
    24     @Override
    25     public List<UserInfo> findAll() {
    26         
    27         return userDao.findAll();
    28     }
    29 
    30 }

    在程序主类中还需要配置事务管理注解,使用注解@EnableTransactionManagement开启事务。

     1 package com.demo;
     2 
     3 import org.springframework.boot.SpringApplication;
     4 import org.springframework.boot.autoconfigure.SpringBootApplication;
     5 import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
     6 import org.springframework.transaction.annotation.EnableTransactionManagement;
     7 
     8 @SpringBootApplication // 启动Springboot程序,而后自带子包扫描
     9 @EnableJpaRepositories(basePackages = "com.demo.dao")
    10 @EnableTransactionManagement // 启动事务管理
    11 public class DemoApplication {
    12 
    13     public static void main(String[] args) {
    14         // 启动Springboot程序
    15         SpringApplication.run(DemoApplication.class, args);
    16     }
    17 
    18 }

    如果在业务层中定义@Transactional注解实现事务的控制,全部使用注解控制必然会造成代码的大量重复。在实际工作中,SpringBoot与事务结合最好的控制方法就是定义一个事务的配置类。取消业务Service层的事务注解配置,并定义TransactionConfig配置类,如下所示:

     1 package com.demo.config;
     2 
     3 import java.util.HashMap;
     4 import java.util.Map;
     5 
     6 import org.aspectj.lang.annotation.Aspect;
     7 import org.springframework.aop.Advisor;
     8 import org.springframework.aop.aspectj.AspectJExpressionPointcut;
     9 import org.springframework.aop.support.DefaultPointcutAdvisor;
    10 import org.springframework.beans.factory.annotation.Autowired;
    11 import org.springframework.context.annotation.Bean;
    12 import org.springframework.context.annotation.Configuration;
    13 import org.springframework.transaction.PlatformTransactionManager;
    14 import org.springframework.transaction.TransactionDefinition;
    15 import org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource;
    16 import org.springframework.transaction.interceptor.RuleBasedTransactionAttribute;
    17 import org.springframework.transaction.interceptor.TransactionAttribute;
    18 import org.springframework.transaction.interceptor.TransactionInterceptor;
    19 
    20 @Configuration // 定义配置Bean
    21 @Aspect // 采用Aop切面处理,定义切面类,切面通常是指封装的用于横向插入系统功能(事务、日志)的类。
    22 public class TransactionConfig {
    23 
    24     private static final int TRANSACTION_METHOD_TIMEOUT = 5; // 事务超时时间为5秒钟
    25 
    26     // 定义切面表达式
    27     private static final String AOP_POINTCUT_EXPRESSION = "execution(* com.demo..service.*.*(..))";
    28 
    29     // 注入事务管理对象
    30     @Autowired
    31     private PlatformTransactionManager transactionManager;
    32 
    33     /**
    34      * 切面名称必须为txAdvice
    35      * 
    36      * @return
    37      */
    38     @Bean(value = "txAdvice")
    39     public TransactionInterceptor transactionConfig() {
    40         // 定义只读事务控制,该事务不需要启动事务支持
    41         RuleBasedTransactionAttribute readOnly = new RuleBasedTransactionAttribute();
    42         // 设置只读事务
    43         readOnly.setReadOnly(true);
    44         readOnly.setPropagationBehavior(TransactionDefinition.PROPAGATION_NOT_SUPPORTED);
    45 
    46         // 定义更新事务,同时设置事务操作的超时时间
    47         RuleBasedTransactionAttribute required = new RuleBasedTransactionAttribute();
    48         required.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
    49         // 设置事务超时时间为5秒钟
    50         required.setTimeout(TRANSACTION_METHOD_TIMEOUT);
    51 
    52         // 定义业务切面
    53         Map<String, TransactionAttribute> transactionmap = new HashMap<String, TransactionAttribute>();
    54         transactionmap.put("add*", required);
    55         transactionmap.put("edit*", required);
    56         transactionmap.put("delete*", required);
    57         transactionmap.put("get*", readOnly);
    58         transactionmap.put("list*", readOnly);
    59         transactionmap.put("find*", readOnly);
    60 
    61         // 使用名称匹配
    62         NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();
    63         source.setNameMap(transactionmap);
    64 
    65         // 对设置名称的方法进行事务操作
    66         TransactionInterceptor transactionInterceptor = new TransactionInterceptor();
    67         transactionInterceptor.setTransactionManager(transactionManager);
    68         transactionInterceptor.setTransactionAttributeSource(source);
    69 
    70         // 返回事务信息
    71         return transactionInterceptor;
    72     }
    73 
    74     @Bean
    75     public Advisor transactionAdviceAdvisor() {
    76         AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
    77         // 定义切面
    78         pointcut.setExpression(AOP_POINTCUT_EXPRESSION);
    79         DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor(pointcut, transactionConfig());
    80         return advisor;
    81     }
    82 
    83 }

    此时程序中的事务控制可以利用TransactionConfig类结合AspectJ切面与业务层中的方法匹配,而后就不再需要业务方法使用@Transactional注解重复定义了,需要注意的是启动主类要加上@EnableTransactionManagement启动事务管理。

  • 相关阅读:
    KVC的取值和赋值
    OC中属性的内存管理
    mysql的通信协议
    Proactor模式&Reactor模式详解
    Linux异步IO学习
    Redis 分布式锁的实现原理
    redis过期键
    智能指针
    std::unique_lock与std::lock_guard
    手撕代码
  • 原文地址:https://www.cnblogs.com/biehongli/p/13984361.html
Copyright © 2011-2022 走看看