首页 > 其他分享 >Spring Boot 集成 RabbitMQ 消息事务(生产者)

Spring Boot 集成 RabbitMQ 消息事务(生产者)

时间:2024-10-10 11:02:33浏览次数:6  
标签:事务 name -- Spring 数据库 Boot RabbitMQ public

1. Spring Boot 集成 RabbitMQ 消息事务(生产者)

1.1. 版本说明

构件 版本
spring-boot 2.7.18
spring-boot-starter-amqp 2.7.18
spring-boot-starter-jdbc 2.7.18
spring-boot-starter-web 2.7.18

1.2. 概览

这里模拟一个常见的业务流程,提供一个 Http 接口,这个接口会向 RabbitMQ 发送一条消息,同时更新数据库。这里涉及到分布式事务,本案例采用最大努力单阶段提交模式来实现事务管理。

1.2.1. 最大努力单阶段提交模式

最大努力单阶段提交模式是相当普遍的,但在开发人员必须注意的某些情况下可能会失败。这是一种非 XA 模式,涉及了许多资源的同步单阶段提交。因为没有使用二阶段提交,它绝不会像 XA 事务那样安全,但是如果参与者意识到妥协,通常就足够了。许多高容量,高吞吐量的事务处理系统通过设置这种方式以达到提高性能的目的。

1.2.2. 成功的业务流程

flowchart TB 1["1. 开始消息事务"] --> 2["2. 发送消息"] --> 3["3. 开始数据库事务"] --> 4["4. 更新数据库"] --> 5["5. 提交数据库事务"] --> 6["6. 提交消息事务"]

1.2.3. 失败的业务流程

flowchart TB 1["1. 开始消息事务"] --> 2["2. 发送消息"] --> 3["3. 开始数据库事务"] --> 4["4. 更新数据库失败"] --> 5["5. 回滚数据库事务"] --> 6["6. 回滚消息事务"]

1.3. 新建数据库表

create table t_user
(
    id   int auto_increment primary key,
    name varchar(20) not null
);

1.4. Spring 配置

spring:
  application:
    name: spring-rabbit-transaction-producer-demo
  rabbitmq:
    addresses: 127.0.0.1:5672
    username: admin
    password: admin
    virtual-host: /
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/demo
    username: root
    password: root

1.5. 定义常量

public class RabbitTransactionProducerDemoConstants {
    public static final String EXCHANGE = "spring-rabbit-transaction-producer-demo-exchange";
    public static final String QUEUE = "spring-rabbit-transaction-producer-demo-queue";
}

1.6. 配置交换机和队列

@Bean
public FanoutExchange exchange() {
    return ExchangeBuilder.fanoutExchange(EXCHANGE).durable(true).build();
}

@Bean
public Queue queue() {
    return QueueBuilder.durable(QUEUE).build();
}

@Bean
public Binding binding() {
    return BindingBuilder.bind(queue()).to(exchange());
}

1.7. 定义 RabbitMQ 消息事务管理器

@Bean(name = "rabbitTransactionManager")
public RabbitTransactionManager rabbitTransactionManager(ConnectionFactory connectionFactory) {
    return new RabbitTransactionManager(connectionFactory);
}

1.8. 定义 RabbitTemplate

@Bean
public RabbitTemplate rabbitTemplate(RabbitTemplateConfigurer configurer, ConnectionFactory connectionFactory) {
    RabbitTemplate template = new RabbitTemplate();
    configurer.configure(template, connectionFactory);
    //Channel 启用事务
    template.setChannelTransacted(true);
    return template;
}

1.9. 定义数据库事务管理器

@Bean(name = "dataSourceTransactionManager")
@Primary
DataSourceTransactionManager dataSourceTransactionManager(DataSource dataSource, ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers) {
    DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(dataSource);
    transactionManagerCustomizers.ifAvailable((customizers) -> customizers.customize(transactionManager));
    return transactionManager;
}

1.10. 测试

@RestController
@Slf4j
public class SpringRabbitTransactionProducerDemo {

    @Resource
    private RabbitTemplate rabbitTemplate;

    @Resource
    private JdbcTemplate jdbcTemplate;

    @Resource
    private TransactionDefinition transactionDefinition;

    @Resource
    private DataSourceTransactionManager dataSourceTransactionManager;

    //Spring 消息事务,指定事务管理器为 RabbitTransactionManager
    @Transactional(rollbackFor = Throwable.class, transactionManager = "rabbitTransactionManager")
    @GetMapping("/transaction")
    public void transaction() {
        String name = "Jason";
        //发送一条消息,接下来因数据库插入数据异常,消息事务回滚,并不会真正把消息发送出去
        rabbitTemplate.convertAndSend(EXCHANGE, null, name);
        //手动开启数据库事务
        TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
        try {
            //往数据库表插入两条主键 id 一样的数据,引起主键 id 重复异常
            jdbcTemplate.update("INSERT INTO t_user (id, name) VALUES (1, ?)", ps -> ps.setString(1, name));
            jdbcTemplate.update("INSERT INTO t_user (id, name) VALUES (1, ?)", ps -> ps.setString(1, name));
            //手动提交数据库事务,因上面插入数据异常,并不会执行到这里
            dataSourceTransactionManager.commit(transactionStatus);
        } catch (Throwable throwable) {
            //捕获异常,手动回滚数据库事务
            dataSourceTransactionManager.rollback(transactionStatus);
            //抛出异常,让 Spring 回滚 RabbitMQ 消息事务
            throw throwable;
        }
    }
}

1.11. 参考资料

标签:事务,name,--,Spring,数据库,Boot,RabbitMQ,public
From: https://www.cnblogs.com/jason207010/p/18455600

相关文章

  • Spring Boot洗衣店订单系统:业务流程优化
    2相关技术2.1MYSQL数据库MySQL是一个真正的多用户、多线程SQL数据库服务器。是基于SQL的客户/服务器模式的关系数据库管理系统,它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等,非常适用于Web站点或者其他......
  • 洗衣店管理新思路:Spring Boot订单管理系统
    2相关技术2.1MYSQL数据库MySQL是一个真正的多用户、多线程SQL数据库服务器。是基于SQL的客户/服务器模式的关系数据库管理系统,它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等,非常适用于Web站点或者其他......
  • 【开题报告+论文+源码】基于Spring Boot+Vue的考研互助交流平台的设计与实现
    项目背景与意义考研作为许多大学毕业生进一步提升学术能力的重要途径,其过程往往伴随着复杂而严峻的挑战。随着信息时代的到来,虽然考研资源逐渐丰富,但信息不对称、缺乏有效交流平台等问题仍然普遍存在,这严重影响了考生的备考效率和信心。在这样的背景下,设计一个集信息共享、交......
  • 【开题报告+论文+源码】基于SpringBoot及Vue的宿舍软装租赁平台
    项目背景与意义随着科技的飞速发展和人们生活水平的不断提升,大学生对于宿舍环境的个性化需求也日益增长。宿舍作为大学生日常生活的重要场所,其软装的舒适度和美观度直接影响到学生的居住体验。因此,宿舍软装租售市场逐渐兴起,并呈现出蓬勃的发展态势。然而,传统的宿舍软装租售方......
  • 【开题报告+论文+源码】基于SpringBoot+Vue的个人博客系统设计与实现
    项目背景与意义当前,个人博客系统作为一种自由、开放的网络平台,已经成为个人展示、交流和分享的重要途径。然而,传统的个人博客系统在功能性和安全性方面存在一些问题。许多传统的个人博客系统功能单一,用户体验不够友好,同时在安全性方面也存在一定隐患,例如容易受到SQL注入、XSS......
  • Spring Boot洗衣店订单处理:高效管理之道
    1系统概述1.1研究背景如今互联网高速发展,网络遍布全球,通过互联网发布的消息能快而方便的传播到世界每个角落,并且互联网上能传播的信息也很广,比如文字、图片、声音、视频等。从而,这种种好处使得互联网成了信息传播的主要途径,社会上各种各样的信息都想尽办法通过互联网进行......
  • 基于SpringBoot+MySQL+SSM+Vue.js的电影票信息管理系统(附论文)
    获取见最下方名片获取见最下方名片获取见最下方名片演示视频基于SpringBoot+MySQL+SSM+Vue.js的电影票信息管理系统(附论文)技术描述开发工具:Idea/Eclipse数据库:MySQLJar包仓库:Maven前端框架:Vue/ElementUI后端框架:Spring+SpringMVC+Mybatis+SpringBoot......
  • 基于SpringBoot+MySQL+SSM+Vue.js的二手家电管理系统(附论文)
    获取见最下方名片获取见最下方名片获取见最下方名片演示视频基于SpringBoot+MySQL+SSM+Vue.js的二手家电管理系统(附论文)技术描述开发工具:Idea/Eclipse数据库:MySQLJar包仓库:Maven前端框架:Vue/ElementUI后端框架:Spring+SpringMVC+Mybatis+SpringBoot文......
  • 深度解析Spring AI:请求与响应机制的核心逻辑
    我们在前面的两个章节中基本上对SpringBoot3版本的新变化进行了全面的回顾,以确保在接下来研究SpringAI时能够避免任何潜在的问题。今天,我们终于可以直接进入主题:SpringAI是如何发起请求并将信息返回给用户的。在接下来的内容中,我们将专注于这一过程,而流式回答和函数回调的相......
  • springboot+vue基于springboot的计算机考研交流平台【开题+程序+论文】
    系统程序文件列表开题报告内容研究背景随着信息技术的飞速发展和高等教育的普及,计算机考研已成为众多学子追求深造的重要途径。然而,考研过程中,学生面临着信息获取不畅、学习资源分散、备考策略迷茫等问题。传统的考研辅导方式往往局限于线下课堂和纸质资料,难以满足学生个性......