示例代码
web层
package com.example.demo.web;
import com.example.demo.service.CustomerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/customer")
public class CustomerResource {
@Autowired
private JmsTemplate jmsTemplate;
@Autowired
private CustomerService customerService;
@PostMapping("/message1/listen")
public void create(@RequestParam String msg) {
jmsTemplate.convertAndSend("customer:msg1:new", msg);
}
@PostMapping("/message1/direct")
public void handle(@RequestParam String msg) {
customerService.handle(msg);
}
@GetMapping("/message")
public String getMsg() {
jmsTemplate.setReceiveTimeout(2000);
Object reply = jmsTemplate.receiveAndConvert("customer:msg:reply");
return String.valueOf(reply);
}
}
service层
package com.example.demo.service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.stereotype.Service;
@Service
public class CustomerService {
private static final Logger logger = LoggerFactory.getLogger(CustomerService.class);
@Autowired
private JmsTemplate jmsTemplate;
@JmsListener(destination = "customer:msg1:new")
public void handle(String msg) {
logger.info("Get msg1 : {}", msg);
String reply = "Reply - " + msg;
jmsTemplate.convertAndSend("customer:msg:reply", reply);
if (msg.contains("error")) {
simulateError();
}
}
private void simulateError() {
throw new RuntimeException("some Data error.");
}
}
实验1 - controller层直接调service层的handle方法
{
"timestamp": 1530174516127,
"status": 500,
"error": "Internal Server Error",
"exception": "java.lang.RuntimeException",
"message": "some Data error.",
"path": "/api/customer/message1/direct"
}
Reply - apple_error
实验1结论:
- 直接调service层的handle方法,session事务只存在于jmsTemplate.convertAndSend("customer:msg:reply", reply)中;
- service的handle方法不存在事务;
实验2 - service层中的handle方法通过监听MQ中的消息被调用
null
实验2结论 :
- 如果service层的handle方法是通过监听被调用,整个方法受session事务的控制,当方法出错,会重试7次,如果还出错,消息将被丢进死信队列,并不会发送到customer:msg:reply队列中;