package cn.learn.rocketmq.spring.transaction;
import org.apache.rocketmq.spring.annotation.RocketMQTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionState;
import org.apache.rocketmq.spring.support.RocketMQHeaders;
import org.springframework.messaging.Message;
import java.util.HashMap;
import java.util.Map;
@RocketMQTransactionListener(txProducerGroup = "myTransactionGroup")
public class TransactionListenerImpl implements RocketMQLocalTransactionListener {
private static Map<String, RocketMQLocalTransactionState> STATE_MAP = new HashMap<>();
/**
* 执行业务逻辑
*
* @param message
* @param o
* @return
*/
@Override
public RocketMQLocalTransactionState executeLocalTransaction(Message message, Object o) {
String transId = (String)message.getHeaders().get(RocketMQHeaders.TRANSACTION_ID);
try {
System.out.println("执行操作1");
Thread.sleep(500);
System.out.println("执行操作2");
Thread.sleep(800);
STATE_MAP.put(transId, RocketMQLocalTransactionState.COMMIT);
return RocketMQLocalTransactionState.COMMIT;
} catch (Exception e) {
e.printStackTrace();
}
STATE_MAP.put(transId, RocketMQLocalTransactionState.ROLLBACK);
return RocketMQLocalTransactionState.ROLLBACK;
}
/**
* 回查
*
* @param message
* @return
*/
@Override
public RocketMQLocalTransactionState checkLocalTransaction(Message message) {
String transId = (String)message.getHeaders().get(RocketMQHeaders.TRANSACTION_ID);
System.out.println("回查消息 -> transId = " + transId + ", state = " + STATE_MAP.get(transId));
return STATE_MAP.get(transId);
}
}
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package org.springframework.messaging;
public interface Message<T> {
T getPayload();
MessageHeaders getHeaders();
}
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package org.apache.rocketmq.spring.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.stereotype.Component;
@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface RocketMQTransactionListener {
String txProducerGroup() default "rocketmq_transaction_default_global_name";
int corePoolSize() default 1;
int maximumPoolSize() default 1;
long keepAliveTime() default 60000L;
int blockingQueueSize() default 2000;
}
package cn.learn.rocketmq.spring.transaction;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Component;
import java.io.UnsupportedEncodingException;
@Component
public class SpringTransactionProducer {
@Autowired
private RocketMQTemplate rocketMQTemplate;
/**
* 发送消息
*
* @param topic
* @param msg
*/
public void sendMsg(String topic, String msg) {
Message message = MessageBuilder.withPayload(msg).build();
// myTransactionGroup要和@RocketMQTransactionListener(txProducerGroup = "myTransactionGroup")定义的一致
this.rocketMQTemplate.sendMessageInTransaction("myTransactionGroup",
topic,
message,
null);
System.out.println("发送消息成功");
}
}
package cn.learn.rocketmq.spring.transaction;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.stereotype.Component;
@Component
@RocketMQMessageListener(topic = "spring-tx-my-topic",
consumerGroup = "learn-consumer",
selectorExpression = "*")
public class SpringTxConsumer implements RocketMQListener<String> {
@Override
public void onMessage(String msg) {
System.out.println("接收到消息 -> " + msg);
}
}
package cn.learn.rocketmq.spring;
import cn.learn.rocketmq.spring.transaction.SpringTransactionProducer;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class TestSpringRocketMQ {
@Autowired
private SpringProducer springProducer;
@Autowired
private SpringTransactionProducer springTransactionProducer;
@Test
public void testSendMsg(){
String msg = "我的第2个SpringRocketMQ消息!";
this.springProducer.sendMsg("spring-my-topic", msg);
System.out.println("发送成功");
}
@Test
public void testSendMsg2(){
this.springTransactionProducer.sendMsg("spring-tx-my-topic", "第2个Spring事务消息");
try {
Thread.sleep(9999999L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
package cn.learn.rocketmq.spring;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}