Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to implement distributed transaction with Spring Boot + RabbitMQ

2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Network Security >

Share

Shulou(Shulou.com)05/31 Report--

Editor to share with you Spring Boot + RabbitMQ how to achieve distributed transactions, I hope you will learn something after reading this article, let's discuss it together!

One: distributed transaction solution

1. Two-phase commit (2PC)

The first phase: the transaction coordinator requires each database involved in the transaction to pre-commit (precommit) this operation and reflects whether it can be committed.

The second phase: the transaction coordinator requires each database to submit data.

The case can be referred to http://blog.itpub.net/28624388/viewspace-2137095/

two。 Compensation transaction (TCC)

TCC is actually the compensation mechanism adopted, and its core idea is to register a corresponding confirmation and compensation (revocation) operation for each operation. It is divided into three stages:

The Try phase is mainly about testing the business system and reserving resources.

The main purpose of the Confirm phase is to confirm the submission of the business system. When the Try phase is executed successfully and the Confirm phase is started, the default Confirm phase will not go wrong. That is, as long as Try succeeds, Confirm will succeed.

The Cancel phase mainly cancels the business executed in the case of business execution error and needs to be rolled back, and reserves resources to be released.

3. Local message table (asynchronously guaranteed)

The implementation of local message table should be the most widely used in the industry, and its core idea is to split the distributed transaction into local transactions for processing.

Basic ideas:

a. The message producer needs to build an additional message table and record the message delivery status. Message tables and business data are committed in a transaction, that is, they are in a database. The message is then sent to the consumer of the message via MQ. If the message fails to send, it will retry to send.

b. The message consumer needs to process the message and complete its own business logic. At this point, if the local transaction is successful, it indicates that the processing has been successful, and if the processing fails, the execution will be retried. If it is a failure of the business, you can send a business compensation message to the manufacturer to notify the manufacturer to roll back and other operations.

c. The producer and consumer scan the local message table regularly and send the unfinished message or failed message again. If there is a reliable automatic reconciliation logic, this scheme is still very practical.

Second: Spring Boot + RabbitMQ distributed transaction implementation

1.pom.xml dependent configuration

Org.springframework.boot spring-boot-starter-amqp

2.application.yaml rabbitmq configuration

# RabbitMQ rabbitmq: host: 112.74.105.178 port: 5672 username: admin password: admin virtual-host: / publisher-confirms: true publisher-returns: true listener: simple: acknowledge-mode: manual

3.RabbitMQConfig.java

@ Configurationpublic class RabbitMQConfig {/ / place the order and dispatch the order storage queue public static final String ORDER_DIC_QUEUE = "order_dis_queue"; / / fill the order queue to determine whether the order has been created public static final String ORDER_CREATE_QUEUE = "order_create_queue"; / / place the order and dispatch the order switch private static final String ORDER_EXCHANGE_NAME = "order_exchange_name" @ Bean public RabbitTemplate rabbitTemplate (ConnectionFactory connectionFactory) {RabbitTemplate template = new RabbitTemplate (connectionFactory); template.setMessageConverter (new Jackson2JsonMessageConverter ()); return template;} @ Bean public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory (ConnectionFactory connectionFactory) {SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory (); factory.setConnectionFactory (connectionFactory) Factory.setMessageConverter (new Jackson2JsonMessageConverter ()); return factory;} @ Bean public Queue OrderDicQueue () {return new Queue (ORDER_DIC_QUEUE);} @ Bean public Queue OrderCreateQueue () {return new Queue (ORDER_CREATE_QUEUE) } @ Bean DirectExchange directOrderExchange () {return new DirectExchange (ORDER_EXCHANGE_NAME);} @ Bean Binding bindingExchangeOrderDicQueue () {return BindingBuilder.bind (OrderDicQueue ()) .to (directOrderExchange ()) .with ("orderRoutingKey") } @ Bean Binding bindingExchangeOrderCreateQueue () {return BindingBuilder.bind (OrderCreateQueue ()) .to (directOrderExchange ()) .with ("orderRoutingKey");}}

4. Message producer

Public class MsgPushInfoServiceImpl extends ServiceImpl implements MsgPushInfoService, RabbitTemplate.ConfirmCallback {@ Autowired private RabbitTemplate rabbitTemplate; public void orderAndDsipatch () {try {String orderId = "123456"; JSONObject jsonObect = new JSONObject (); jsonObect.put ("orderId", orderId) String msg = jsonObect.toString (); System.out.println ("msg:" + msg); MessageProperties messageProperties = new MessageProperties (); messageProperties.setContentType ("application/json"); messageProperties.setMessageId (orderId); Message message = new Message (msg.getBytes (), messageProperties) CorrelationData correlationData = new CorrelationData (orderId); rabbitTemplate.setMandatory (true); rabbitTemplate.setConfirmCallback (this); rabbitTemplate.convertAndSend ("order_exchange_name", "orderRoutingKey", message, correlationData) } catch (Exception e) {e.printStackTrace ();}} @ Override public void confirm (CorrelationData correlationData, boolean ack, String cause) {String orderId = correlationData.getId (); System.out.println ("message id:" + orderId) If (ack) {/ / message sent successfully System.out.println ("message sent confirmed successfully");} else {/ / retry mechanism System.out.println ("message delivery confirmation failed:" + cause);}

5. Message consumer

@ Componentpublic class DispatchReceiver {@ RabbitHandler @ RabbitListener (queues = "order_dis_queue", containerFactory = "rabbitListenerContainerFactory") public void process (Message message, Channel channel) {System.out.println ("rev:" + message.getMessageProperties (). GetMessageId ()); try {System.out.println ("= basicNack=" + message.getMessageProperties (). GetDeliveryTag ()) / / if the business processing succeeds, delete the message channel.basicNack (message.getMessageProperties (). GetDeliveryTag (), false, false); / / if the business processing fails, send the compensation message} catch (Exception e) {e.printStackTrace () After reading this article, I believe you have some understanding of "how Spring Boot + RabbitMQ implements distributed transactions". If you want to know more about it, you are welcome to follow the industry information channel. Thank you for reading!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Network Security

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report