广告
返回顶部
首页 > 资讯 > 后端开发 > Python >使用@TransactionalEventListener监听事务教程
  • 927
分享到

使用@TransactionalEventListener监听事务教程

2024-04-02 19:04:59 927人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

目录@TransactionalEventListener监听事务最近在项目遇到一个问题解决办法:@TransactionalEventListener拓展注解@Transactio

@TransactionalEventListener监听事务

项目背景

最近在项目遇到一个问题

A方法体内有 INSERT、UPDATE或者DELETE操作,最后会发送一段MQ给外部,外部接收到MQ后会再发送一段请求过来,系统收到请求后会执行B方法,B方法会依赖A方法修改后的结果,这就有一个问题,如果A方法事务没有提交;且B方法的请求过来了会查询到事务未提交前的状态,这就会有问题

解决办法:@TransactionalEventListener

spring4.2+,有一种叫做TransactionEventListener的方式,能够控制在事务的时候Event事件的处理方式。 我们知道,Spring的发布订阅模型实际上并不是异步的,而是同步的来将代码进行解耦。而TransactionEventListener仍是通过这种方式,只不过加入了回调的方式来解决,这样就能够在事务进行Commited,Rollback…等的时候才会去进行Event的处理。

具体实现


//创建一个事件类
package com.qk.cas.config;
import org.springframework.context.ApplicationEvent;
public class MyTransactionEvent extends ApplicationEvent {
    private static final long serialVersionUID = 1L;
    private IProcesser processer;
    public MyTransactionEvent(IProcesser processer) {
        super(processer);
        this.processer = processer;
    }
    public IProcesser getProcesser() {
        return this.processer;
    }
    @FunctionalInterface
    public interface IProcesser {
        void handle();
    }
}
//创建一个监听类
package com.qk.cas.config;
import org.springframework.stereotype.Component;
import org.springframework.transaction.event.TransactionPhase;
import org.springframework.transaction.event.TransactionalEventListener;
@Component
public class MyTransactionListener {
    @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
    public void hanldeOrderCreatedEvent(MyTransactionEvent event) {
        event.getProcesser().handle();
    }
}
//MQ方法的变动
    @Autowired
    private ApplicationEventPublisher eventPublisher;
    @Autowired
    private AmqpTemplate rabbitTemplate;
    public void sendCreditResult(String applyNo, String JSONString) {
        eventPublisher.publishEvent(new MyTransactionEvent(() -> {
            LOGGER.info("MQ。APPLY_NO:[{}]。KEY:[{}]。通知报文:[{}]", applyNo, Queues.CREDIT_RESULT, jsonString);
            rabbitTemplate.convertAndSend(Queues.CREDIT_RESULT, jsonString);
        }));
    }

拓展

@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) 只有当前事务提交之后,才会执行事件监听的方法,其中参数phase默认为AFTER_COMMIT,共有四个枚举:


public enum TransactionPhase {
    
    BEFORE_COMMIT,
    
    AFTER_COMMIT,
    
    AFTER_ROLLBACK,
    
    AFTER_COMPLETION
}

注解@TransactionalEventListener

例如 用户注册之后需要计算用户的邀请关系,递归操作。如果注册的时候包含多步验证,生成基本初始化数据,这时候我们通过mq发送消息来处理这个邀请关系,会出现一个问题,就是用户还没注册数据还没入库,邀请关系就开始执行,但是查不到数据,导致出错。

@TransactionalEventListener 可以实现事务的监听,可以在提交之后再进行操作。

监听的对象


package com.jinglitong.springshop.interceptor; 
import com.jinglitong.springshop.entity.Customer;
import org.springframework.context.ApplicationEvent;
  
public class ReGCustomerEvent extends ApplicationEvent{
    public RegCustomerEvent(Customer customer){
        super(customer);
    }
}

监听到之后的操作


package com.jinglitong.springshop.interceptor; 
import com.alibaba.fastjson.JSON;
import com.jinglitong.springshop.entity.Customer;
import com.jinglitong.springshop.entity.MqMessageRecord;
import com.jinglitong.springshop.servcie.MqMessageRecordService;
import com.jinglitong.springshop.util.AliMQServiceUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.transaction.event.TransactionPhase;
import org.springframework.transaction.event.TransactionalEventListener;  
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
 
@Component
@Slf4j
public class RegCustomerListener {
 
    @Value("${aliyun.mq.order.topic}")
    private String topic;
 
    @Value("${aliyun.mq.reGISt.product}")
    private String registGroup;
 
    @Value("${aliyun.mq.regist.tag}")
    private String registTag;
 
    @Autowired
    MqMessageRecordService mqMessageRecordService;
 
    @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
    public void hanldeRegCustomerEvent(RegCustomerEvent regCustomerEvent) {
        Customer cust = (Customer) regCustomerEvent.getSource();
        Map<String, String> map = new HashMap<String, String>();
        map.put("custId", cust.getZid());
        map.put("account", cust.getAccount());
        log.info("put regist notice to Mq start");
        String hdResult = AliMQServiceUtil.createNeWorder(cust.getZid(), JSON.toJSONString(map),topic,registTag,registGroup);
        MqMessageRecord insert = buidBean(cust.getZid(),hdResult,registTag,JSON.toJSONString(map),registGroup);
        if(StringUtils.isEmpty(hdResult)) {
            insert.setStatus(false);
        }else {
            insert.setStatus(true);
        }
        mqMessageRecordService.insertRecord(insert);
        log.info("put regist notice to Mq end");
        log.info("regist notice userId : " + cust.getAccount());
    }
 
    private MqMessageRecord buidBean (String custId,String result ,String tag,String jsonStr,String groupId) {
        MqMessageRecord msg = new MqMessageRecord();
        msg.setFlowId(custId);
        msg.setGroupName(groupId);
        msg.setTopic(topic);
        msg.setTag(tag);
        msg.setMsgId(result);
        msg.setDataBody(jsonStr);
        msg.setSendType(3);
        msg.setGroupType(1);
        msg.setCreateTime(new Date());
        return msg;
    } 
}
@Autowired
    private ApplicationEventPublisher applicationEventPublisher;
 
applicationEventPublisher.publishEvent(new RegCustomerEvent (XXX));

这样可以确保数据入库之后再进行异步计算

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

--结束END--

本文标题: 使用@TransactionalEventListener监听事务教程

本文链接: https://www.lsjlt.com/news/135865.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 使用@TransactionalEventListener监听事务教程
    目录@TransactionalEventListener监听事务最近在项目遇到一个问题解决办法:@TransactionalEventListener拓展注解@Transactio...
    99+
    2022-11-12
  • 使用Spring怎么监听事件
    使用Spring怎么监听事件?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。一、观察者模式先来看下观察者模式,举个例子警察和军人是观察者,犯罪嫌疑人是被观察者代码实现:定义被观察...
    99+
    2023-06-15
  • springboot事件监听器怎么使用
    本篇内容介绍了“springboot事件监听器怎么使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!引导案例下面看一个简单的案例,@Conf...
    99+
    2023-07-02
  • vue如何使用监听事件 v-on
    这篇文章主要介绍了vue如何使用监听事件 v-on,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。代码:问题:如何将button和counte...
    99+
    2022-10-19
  • Vue的addEventListener()监听事件怎么使用
    本篇内容介绍了“Vue的addEventListener()监听事件怎么使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、语法eleme...
    99+
    2023-07-04
  • 详解Vue3中Watch监听事件的使用
    目录一、watch的使用1、引入watch2、多个数据源监听3、监听数组变化4、侦听对象5、结论一、watch的使用 watch(WatcherSource, Callback, [...
    99+
    2023-02-10
    Vue3 Watch监听事件使用 Vue3 Watch监听 Vue3 Watch
  • 使用layui监听器监听select下拉框,事件绑定不成功怎么办
    这篇文章主要为大家展示了“使用layui监听器监听select下拉框,事件绑定不成功怎么办”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“使用layui监听器监听...
    99+
    2022-10-19
  • SpringBootApplicationListener事件监听接口使用问题探究
    终日惶惶,不知归路;一日写起代码,突发奇想,若是在运行时发现自定义上下文的数据丢失,我们该如何解决处理数据丢失的问题? 问题复现一下,大家看下面的代码,观察是否有问题,又该如何解决这...
    99+
    2023-05-14
    SpringBoot ApplicationListener SpringBoot事件监听接口
  • springboot应用服务启动事件的监听实现
    目录一、简介二、常用场景介绍二、代码小实验 通过@Component定义方式实现通过@Bean定义方式实现三、执行测试四、总结五、问题总结一、简介 Spring Boot提供了两个接...
    99+
    2022-11-13
  • thinkphp的事件绑定、监听和订阅怎么使用
    这篇文章主要介绍了thinkphp的事件绑定、监听和订阅怎么使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇thinkphp的事件绑定、监听和订阅怎么使用文章都会有所收获,下面我们一起来看看吧。事件是什么事件...
    99+
    2023-06-30
  • zookeeper+Springboot实现服务器动态上下线监听教程详解
    目录zookeeper+Springboot实现服务器动态上下线监听教程一.什么是服务器动态上下线监听二.为什么要实现对服务器上下线的监听三.编码实现四.测试1.启动客户端,开启监听...
    99+
    2022-11-13
  • springboot应用服务启动事件的监听怎么实现
    本篇内容主要讲解“springboot应用服务启动事件的监听怎么实现”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“springboot应用服务启动事件的监听怎么实现”吧!一、简介Spring B...
    99+
    2023-06-29
  • SpringBoot ApplicationListener事件监听接口使用问题怎么解决
    这篇文章主要介绍“SpringBoot ApplicationListener事件监听接口使用问题怎么解决”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“SpringBoot Ap...
    99+
    2023-07-05
  • 微信小程序如何监听用户主动截屏事件
    这篇文章主要为大家展示了微信小程序如何监听用户主动截屏事件,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带大家一起来研究并学习一下“微信小程序如何监听用户主动截屏事件”这篇文章吧。监听用户主动截屏事件,用户使用系统截屏按键截...
    99+
    2023-06-26
  • 微信小程序中如何监听用户主动截屏事件
    这篇“微信小程序中如何监听用户主动截屏事件”除了程序员外大部分人都不太理解,今天小编为了让大家更加理解“微信小程序中如何监听用户主动截屏事件”,给大家总结了以下内容,具有一定借鉴价值,内容详细步骤清晰,细节处理妥当,希望大家通过这篇文章有所...
    99+
    2023-06-26
  • springbootmetrics监控指标使用教程
    目录springbootmetrics是什么?一、引入依赖二、配置启用三、独立的web服务四、全局标签设置五、自定义指标收集六、推送or拉取指标引入依赖启用push模式 spring...
    99+
    2022-11-13
  • 使用script命令怎么监听多个服务
    这篇文章给大家介绍使用script命令怎么监听多个服务,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。"scripts": {  "test":&nb...
    99+
    2023-06-09
  • Java Web3J :使用web3j监听、查询、订阅智能合约的事件
    前面有文章写如何使用Docker-compose方式部署blockscout浏览器+charts图表,区块链浏览器已经部署成功了,同时我们在链上增加了治理投票流程,如何实时的把治理事件快速同步到浏...
    99+
    2023-09-10
    java web3 智能合约 websocket 笔记 经验分享 maven
  • 从零开始学习Node.js系列教程五:服务器监听方法示例
    本文实例讲述了Node.js服务器监听方法。分享给大家供大家参考,具体如下: httpsnifferInvoke.js var http = require('http'); var sniffer =...
    99+
    2022-06-04
    示例 从零开始 服务器
  • 详解Vue3中侦听器watch的使用教程
    目录watch 侦听器使用。侦听器监听 reactive监听多个参数执行各自逻辑监听多个参数执行相同逻辑上一节我们简单的介绍了一下 vue3 项目中的计算属性,这一节我们继续 vue...
    99+
    2022-11-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作