Spring专题

使用Spring JMS处理消息事务源码案例

  

消费者在接收JMS异步消息的过程中会发生执行错误,这可能会导致信息的丢失。该源码展示如何使用本地事务解决这个问题。这种解决方案可能会导致在某些情况下消息的重复(例如,当它会将信息储存到数据库,然后监听执行失败)。之所以出现这种情况是因为JMS交易是独立于像数据库等事务性资源。如果您的处理不是幂等或者如果您的应用程序不支持重复消息检测,那么你将不得不使用分布式事务。分布式事务是超出了本源码案例的范围。

源码下载见github

消费者的代码如下:


01 @Component("notificationProcessor")
02 public class NotificationProcessor implements MessageListener {
03     private static Logger logger = LoggerFactory.getLogger(NotificationProcessor.class);
04      
05     @Autowired
06     private JdbcTemplate jdbcTemplate;
07      
08     @Override
09     public void onMessage(Message message) {
10         try {
11             Notification notification = (Notification) ((ObjectMessage) message).getObject();
12             logger.info("Received notification | Id: "+notification.getId()+" | Redelivery: "+getDeliveryNumber(message));
13              
14             checkPreprocessException(notification);
15             saveToBD(notification);
16             checkPostprocessException(message, notification);
17         } catch (JMSException e) {
18             throw JmsUtils.convertJmsAccessException(e);
19         }
20     }  
21     ...
22 }

当带有id=1的notification到达时, checkPreprocessException 将抛出一个运行错误,在存储消息到数据库之前引法一个错误。

当带有id=2的notification到达时,checkPostprocessException方法将抛出一个exception,这样在存储数据库之后引发一个错误。

当消息已经被发送以后,getDeliveryNumber 方法返回次数,这里使用事务机制

 saveToDB是存储一个notification 到数据库.

 

Spring各种源码项目下载