RabbitMQ是基于AMQP协议实现的,该协议实现了事务机制,因此RabbitMQ也支持事务机制.
SpringAMQP也提供了对事务相关的操作.RabbitMQ事务允许开发者确保消息的发送和接收是原子性的,要么全部成功,要么全部失败.
配置事务管理器
@Configuration
public class RabbitTemplateConfig {
//事务
@Bean("transRabbitTemplate")
public RabbitTemplate transRabbitTemplate(ConnectionFactory connectionFactory){
RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
//设置setChannelTransacted为true
rabbitTemplate.setChannelTransacted(true);
return rabbitTemplate;
}
//配置事务管理器
@Bean
public RabbitTransactionManager rabbitTransactionManager(ConnectionFactory connectionFactory){
return new RabbitTransactionManager(connectionFactory);
}
}
声明队列
@Configuration
public class RabbitMQConfig {
@Bean("transQueue")
public Queue transQueue(){
return QueueBuilder.durable(Constant.TRANS_QUEUE).build();
}
}
生产者代码
@RestController
@RequestMapping("/producer")
public class ProducerController {
@Resource(name = "transRabbitTemplate")
private RabbitTemplate transRabbitTemplate;
@Transactional
@RequestMapping("/trans")
public String trans(){
//1. rabbitTemplate.setChannelTransacted(true);设置事务属性为true
//2. 开启@Transactional注解
//3. RabbitTransactionManager
System.out.println("trans test...");
transRabbitTemplate.convertAndSend("",Constant.TRANS_QUEUE, "trans test 1...");
int num = 5/0;
transRabbitTemplate.convertAndSend("",Constant.TRANS_QUEUE, "trans test 2...");
return "消息发送成功";
}
}
测试
下面基于我们编写的代码来进行一下简单的测试
加@Transactional
注解和不加@Transactional
注解
我们先把注解屏蔽掉调用接口
此时再看看我们RabbitMQ的管理界面,可以看到第一条消息发送成功了
把消息删掉再加上@Transactional
注解,再调用接口
可以看到此时我们的队列里就不会收到消息了