例如 用户注册之后需要计算用户的邀请关系,递归操作。如果注册的时候包含多步验证,生成基本初始化数据,这时候我们通过mq发送消息来处理这个邀请关系,会出现一个问题,就是用户还没注册数据还没入库,邀请关系就开始执行,但是查不到数据,导致出错。
@TransactionalEventListener 可以实现事务的监听,可以在提交之后再进行操作。
监听的对象
package com.jinglitong.springshop.interceptor;
import com.jinglitong.springshop.entity.Customer;
import org.springframework.context.ApplicationEvent;
public class RegCustomerEvent extends ApplicationEvent{
public RegCustomerEvent(Customer customer){
super(customer);
}
}
监听到之后的操作
package com.jinglitong.springshop.interceptor;
import com.alibaba.fastjson.JSON;
import com.jinglitong.springshop.entity.Customer;
import com.jinglitong.springshop.entity.MqMessageRecord;
import com.jinglitong.springshop.servcie.MqMessageRecordService;
import com.jinglitong.springshop.util.AliMQServiceUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.transaction.event.TransactionPhase;
import org.springframework.transaction.event.TransactionalEventListener;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@Component
@Slf4j
public class RegCustomerListener {
@Value("${aliyun.mq.order.topic}")
private String topic;
@Value("${aliyun.mq.regist.product}")
private String registGroup;
@Value("${aliyun.mq.regist.tag}")
private String registTag;
@Autowired
MqMessageRecordService mqMessageRecordService;
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
public void hanldeRegCustomerEvent(RegCustomerEvent regCustomerEvent) {
Customer cust = (Customer) regCustomerEvent.getSource();
Map<String, String> map = new HashMap<String, String>();
map.put("custId", cust.getZid());
map.put("account", cust.getAccount());
log.info("put regist notice to Mq start");
String hdResult = AliMQServiceUtil.createNewOrder(cust.getZid(), JSON.toJSONString(map),topic,registTag,registGroup);
MqMessageRecord insert = buidBean(cust.getZid(),hdResult,registTag,JSON.toJSONString(map),registGroup);
if(StringUtils.isEmpty(hdResult)) {
insert.setStatus(false);
}else {
insert.setStatus(true);
}
mqMessageRecordService.insertRecord(insert);
log.info("put regist notice to Mq end");
log.info("regist notice userId : " + cust.getAccount());
}
private MqMessageRecord buidBean (String custId,String result ,String tag,String jsonStr,String groupId) {
MqMessageRecord msg = new MqMessageRecord();
msg.setFlowId(custId);
msg.setGroupName(groupId);
msg.setTopic(topic);
msg.setTag(tag);
msg.setMsgId(result);
msg.setDataBody(jsonStr);
msg.setSendType(3);
msg.setGroupType(1);
msg.setCreateTime(new Date());
return msg;
}
}
@Autowired
private ApplicationEventPublisher applicationEventPublisher;
applicationEventPublisher.publishEvent(new RegCustomerEvent (XXX));
这样可以确保数据入库之后再进行异步计算