用spring-boot-starter实现事务的统一配置

news2024/10/6 20:39:28

一、前言

微服务架构下,多个微服务都需要事务操作,如果在每个微服务下都从头配置事务,将非常繁锁。事务配置具有高度的一致性,可以抽取出来,制作starter,在需要配置事务的服务中引入starter依赖即可。

  • 采用springAOP的方式实现事务

  • 制作过程可以参考:

    • 自定义启动器 Starter【保姆级教程】
    • 用starter实现Oauth2中资源服务的统一配置

二、制作starter

1、完整结构图

在这里插入图片描述

2、引用模块

名称:tuwer-transaction-spring-boot-starter

引用模块用于外部引用。只有pom.xml文件

  • pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.tuwer</groupId>
    <artifactId>tuwer-transaction-spring-boot-starter</artifactId>
    <version>1.0-SNAPSHOT</version>
    <description>事务starter</description>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <!-- 编译编码 -->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <!-- 自动配置模块 -->
        <dependency>
            <groupId>com.tuwer</groupId>
            <artifactId>tuwer-transaction-spring-boot-starter-autoconfigure</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>
</project>

3、自动配置模块

名称:tuwer-transaction-spring-boot-starter-autoconfigure\

1> pom.xml

使用jdbc的事务管理器

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.7</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.tuwer</groupId>
    <artifactId>tuwer-transaction-spring-boot-starter-autoconfigure</artifactId>
    <version>1.0-SNAPSHOT</version>
    <description>事务starter自动配置模块</description>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <!-- 编译编码 -->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <!-- 基础启动器 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <!-- aop -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <!-- 数据库 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
    </dependencies>
</project>

2> 切入点属性类

  • 用于外部配置切入点

  • 可以配置多个

  • 如果没有配置,就使用默认的:execution(* com.tuwer.service..*Impl.*(..)),【com.tuwer.service】包及子包下,所有以【Impl】结尾的类的所有方法

package com.tuwer.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.util.CollectionUtils;

import java.util.HashSet;
import java.util.Set;

/**
 * <p>事务属性类</p>
 *
 * @author 土味儿
 * Date 2023/4/17
 * @version 1.0
 */
@ConfigurationProperties(prefix = "tuwer-transaction")
public class TransactionProperty {
    /**
     * 切入点(可以有多个)
     * 格式必须符合要求
     */
    private Set<String> pointcut = new HashSet<>();

    /**
     * 获取切入点表达式(可以有多个组合)
     * -----------------------------------
     * execution(...) || execution(...)
     * -----------------------------------
     * @return
     */
    public String getPointcutExpression() {
        // 如果set集合为null,或没有值时,使用默认值
        if(CollectionUtils.isEmpty(this.pointcut)){
            // 默认切入点:【com.tuwer.service】包及子包下,所有以【Impl】结尾的类的所有方法
            return "execution(* com.tuwer.service..*Impl.*(..))";
        }

        StringBuilder sb = new StringBuilder();
        // 组合多个切入点
        for (String p : this.pointcut) {
            sb.append(" || ").append("execution(").append(p).append(")");
        }

        // 组合后,去除最前面的" || "返回
        return sb.substring(3);
    }

    public void setPointcut(Set<String> pointcut) {
         this.pointcut = pointcut;
    }
}

外部配置切入点示例:

由于切入点中有特殊字符*,所以需要加入引号:单引号或双引号都可以

# 事务切入点
tuwer-transaction:
  pointcut:
    - '* com.tuwer1231.service..*Impl.*(..))'
    - '* com.tuwer.service123..*Impl.*(..))'
    - '* com.tuwer345.service123..*Impl.*(..))'

3> 切面自动配置类

package com.tuwer.config;

import org.aspectj.lang.annotation.Aspect;
import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionManager;
import org.springframework.transaction.interceptor.DefaultTransactionAttribute;
import org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource;
import org.springframework.transaction.interceptor.TransactionInterceptor;

import javax.annotation.Resource;

/**
 * <p>事务自动配置类</p>
 *
 * @author 土味儿
 * Date 2023/4/17
 * @version 1.0
 */
@Aspect
@Configuration
@EnableConfigurationProperties(TransactionProperty.class)
public class TuwerTransactionAutoConfiguration {
    /**
     * 注入 TransactionProperty 属性配置类
     */
    @Resource
    private TransactionProperty transactionProperty;

    /**
     * 注入事务管理器
     */
    @Resource
    private TransactionManager transactionManager;

    /**
     * 定义事务增强
     *
     * @return
     */
    @Bean
    public TransactionInterceptor txAdvice() {
        NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();
        // 查询等;只读
        DefaultTransactionAttribute readonlyAttr = new DefaultTransactionAttribute();
        readonlyAttr.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        readonlyAttr.setReadOnly(true);

        source.addTransactionalMethod("get*", readonlyAttr);
        source.addTransactionalMethod("select*", readonlyAttr);
        source.addTransactionalMethod("query*", readonlyAttr);
        source.addTransactionalMethod("load*", readonlyAttr);
        source.addTransactionalMethod("search*", readonlyAttr);
        source.addTransactionalMethod("find*", readonlyAttr);
        source.addTransactionalMethod("list*", readonlyAttr);
        source.addTransactionalMethod("count*", readonlyAttr);
        source.addTransactionalMethod("is*", readonlyAttr);

        // 增删改
        DefaultTransactionAttribute otherAttr = new DefaultTransactionAttribute();
        otherAttr.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);

        source.addTransactionalMethod("*", otherAttr);

        return new TransactionInterceptor(transactionManager, source);
    }

    /**
     * 织入事务
     *
     * @return
     */
    @Bean
    public Advisor txAdviceAdvisor() {
        // 切入点
        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
        pointcut.setExpression(transactionProperty.getPointcutExpression());

        return new DefaultPointcutAdvisor(pointcut, txAdvice());
    }
}

4> spring.factories

指明自动配置类的地址,在 resources 目录下编写一个自己的 META-INF\spring.factories

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  com.tuwer.config.TuwerTransactionAutoConfiguration

5> Install

把starter安装install到本地maven仓库中

三、使用说明

1、引入starter依赖

<!-- 事务starter -->
<dependency>
	<groupId>com.tuwer</groupId>
	<artifactId>tuwer-transaction-spring-boot-starter</artifactId>
	<version>1.0-SNAPSHOT</version>
</dependency>

2、配置切入点

如果不配置,就使用默认的切入点;此步骤可以省略。

至此,事务配置就OK了!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/443481.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

NFS(UOS)

appsrv 172.16.146.11 strogesrv 172.16.146.53 共享/data/share目录 用于存储app主机的web数据 仅允许stora访问该共享 安装nfs apt install nfs-common nfs-kernel-server -y mkdir /data/share /data/share 172.16.146.50(rw,sync,no_root_squash,insecure) 重启服…

志特转债上市价格预测

志特转债 基本信息 转债名称&#xff1a;志特转债&#xff0c;评级&#xff1a;A&#xff0c;发行规模&#xff1a;6.14033亿元。 正股名称&#xff1a;志特新材&#xff0c;今日收盘价&#xff1a;35.6元&#xff0c;转股价格&#xff1a;41.08元。 当前转股价值 转债面值 / …

微服务学习高级篇【5】之服务异步通信(rabbitmq的高级特性)

文章目录 环境准备&#xff1a;MQ部署【docker环境】消息可靠性生产者消息确认项目配置定义Return回调和ConfirmCallback 消息持久化交换机持久化队列持久化消息持久化 消费者消息确认none模式演示 消费失败重试机制本地重试失败策略 总结 死信交换机初识死信交换机死信交换机接…

【DHCP原理与配置】

目录 一、了解DHCP服务使用DHCP的好处DHCP的分配方式 二、DHCP的租约过程传输协议端口DHCP的IP地址自动获取工作原理 三、配置DHCP服务器安装dhcp查看配置文件根据配置文件提示查看相关文档 四、模拟外网和内网互通进入主机1的设置进入主机2的设置复制dhcp文件&#xff0c;修改…

Nginx 优化与防盗链

Ngnix优化主要有两种&#xff0c;一种是配置上的优化&#xff0c;一种是内核上的优化 实验准备&#xff1a;安装好一台Nginx服务器&#xff0c;IP&#xff1a;192.168.126.22&#xff0c;域名&#xff1a;www.accp.com 浏览器访问nginx服务器此时F12查看网页信息&#xff0c;可…

MySQL之表的约束

目录 一 空属性 定义 如何设置 示例 影响&#xff1a; 二 默认值 定义 示例 影响&#xff1a; 三 列描述 定义 示例 影响&#xff1a; 四 zerofill 定义&#xff1a; 示例&#xff1a; 影响&#xff1a; 五 主键 定义 主键的性质是什么&#xff1a; 为什么要…

C++——一种特殊的二叉搜索树之红黑树

目录 1 红黑树的概念2 红黑树的性质3 红黑树节点的定义4 红黑树的插入操作情况一: cur为红&#xff0c;p为红&#xff0c;g为黑&#xff0c;u存在且为红。情况二: cur为红&#xff0c;p为红&#xff0c;g为黑&#xff08;不存在连续的红结点&#xff09;&#xff0c;u不存在/u存…

设计模式 -- 适配器模式

前言 月是一轮明镜,晶莹剔透,代表着一张白纸(啥也不懂) 央是一片海洋,海乃百川,代表着一块海绵(吸纳万物) 泽是一柄利剑,千锤百炼,代表着千百锤炼(输入输出) 月央泽,学习的一种过程,从白纸->吸收各种知识->不断输入输出变成自己的内容 希望大家一起坚持这个过程,也同…

第五篇 Spring 集合注入、作用域

《Spring》篇章整体栏目 ————————————————————————————— 【第一章】spring 概念与体系结构 【第二章】spring IoC 的工作原理 【第三章】spring IOC与Bean环境搭建与应用 【第四章】spring bean定义 【第五章】Spring 集合注入、作用域 【第六章】…

时间序列分析卫星重力梯度观测值

阚昊宇 1 时间序列图 导入数据&#xff0c;共2880历元&#xff08;86370 s&#xff09;数据&#xff0c;取前2400历元&#xff08;72000 s&#xff09;数据作为训练集&#xff0c;后480历元作为测试集。将训练集绘制时间序列图如下图 1红色线所示&#xff0c;可见明显的自相关…

elementUI-el-table组件使用总结

一、背景 vue2项目中用到el-table这个组件&#xff0c;但基础的功能不够用&#xff0c;所以需要自定义 二、表头自定义 比如要让表头展现出下面的形式&#xff1a; 只需使用 slot"header" slot-scope"scope" 对插槽进行定义&#xff0c;并绑定变量 <…

快手视频艾特实操教学分享,什么是艾特脚本,评论区艾特引流脚本讲解!

大家好我是你们的小编一辞脚本&#xff0c;今天给大家分享新的知识&#xff0c;很开心可以在CSDN平台分享知识给大家,很多伙伴看不到代码我先录制一下视频 在给大家做代码&#xff0c;给大家分享一下快手艾特脚本的知识和视频演示 不懂的小伙伴可以认真看一下&#xff0c;我们…

Windows系统开启防火墙,Ubuntu与Windows互通

1.启用Windows系统防火墙&#xff0c;&#xff0c;单击"高级设置" 2.单击“入站2规则” 3.单击 “新建规则“ 4.选择“端口” 端口号设置hanwin NFS中包括的端口号。 5.选择 TCP 填写 hanewin中的端口号&#xff0c;然后单击“确认” 6.单击“入站规则” 7.右击 nf…

JAVAWeb06-动态WEB开发核心Servlet-03

1. HttpServletRequest 1.1 HttpServletRequest 介绍 HttpServletRequest 对象代表客户端的请求当客户端/浏览器通过 HTTP 协议访问服务器时&#xff0c;HTTP 请求头中的所有信息都封装在这 个对象中通过这个对象的方法&#xff0c;可以获得客户端这些信息。 1.2 HttpServle…

HTTP请求知识

一次完整的HTTP请求所经历的步骤 1&#xff1a;首先进行DNS域名解析(本地浏览器缓存&#xff0c;操作系统缓存或者DNS服务器)&#xff0c;首先会搜索浏览器自身的DNS缓存(缓存时间比较短&#xff0c;大概只有1分钟&#xff0c;且只能容纳1000条缓存) 如果浏览器自身的缓存里面…

什么是 MySQL 监控

MySQL是一个开源的关系数据库管理系统&#xff0c;它基于客户端-服务器模型运行&#xff0c;使用SQL作为其通信模式。它是世界上第二受欢迎的数据库&#xff0c;因为它具有灵活性和可扩展性、高安全性、易用性以及无缝处理大型数据集的能力。由于其广泛的功能&#xff0c;MySQL…

ThinkPHP5.1框架通过Composer下载安装

5.1版本开始&#xff0c;官网不再提供下载版本&#xff0c;请使用Composer或者git方式安装和更新。所以想安装Tp51需要通过Composer或者git方式安装 通过Composer方式安装&#xff1a; 一、 先下载Composer Wondows 平台上&#xff0c;我们只需要下载 [Composer-Setup.exe] (h…

4个Python库来美化你的Matplotlib图表

Matplotlib是一个被广泛使用的Python数据可视化库&#xff0c;相信很多人都使用过。 但是有时候总会觉得&#xff0c;Matplotlib做出来的图表不是很好看、不美观。 今天就给大家分享四个美化Matplotlib图表的Python库&#xff0c;它们可以轻松让你的Matplotlib图表变得好看&…

移远通信笔试题

限时60分钟 1.下列关于栈叙述正确的是 A A) 栈顶元素最先能被删除 B&#xff09;栈顶元素最后才能被删除 C&#xff09;栈底元素永远不能被删除 D&#xff09;以上三种都不对 在栈中&#xff0c;最后被压入的元素总是在栈顶上方&#xff0c;而栈顶元素总是最先被弹出的元…

面试题30天打卡-day09

1、一条 SQL 语句在 MySQL 中的执行过程是怎样的&#xff1f; client 根据SQL语法&#xff0c;定义好SQL语句&#xff0c;向MySQL建立连接连接器&#xff1a;client 首先要与 MySQL 建立连接&#xff0c;这就需要一个连接器&#xff0c;负责与 client 建立连接、权限验证、管理…