有时我们需要在某一方法事务提交后再执行一些操作,这些操作可能涉及到提交的数据,如要查询上一步提交后的数据这种 情况,这时我们希望能实现在上一步事务提交后再执行后面的操作。
Spring 中可以使用 ApplicationEvent 事件监听来实现事务监听。
新建事件类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
public class TodoPushEvent extends ApplicationEvent { private List processTaskInfos; public TodoPushEvent(Object source, List processTaskInfos) { super(source); this.processTaskInfos = processTaskInfos; } public List getProcessTaskInfos() { return processTaskInfos; } }
|
新建事件监听器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
|
@Component @Slf4j public class TodoPushListener { @Autowired private IYnjtTaskSendService iYnjtTaskSendService; private static final Logger LOGGER = LoggerFactory.getLogger(TodoPushListener.class); @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) public void onApplicationEvent(TodoPushEvent todoPushEvent){ List processTaskInfos = todoPushEvent.getProcessTaskInfos(); Task taskEntity = (Task) todoPushEvent.getSource(); List taskInfos = processTaskInfos.stream().filter(processTaskInfo -> !StringUtils.equals(processTaskInfo.getId(),taskEntity.getId()) ) .collect(Collectors.toList()); YnjtTaskDTO ynjtTaskDTO = new YnjtTaskDTO().setTaskId(Long.parseLong(taskEntity.getId())).setProcInstId(Long.parseLong(taskEntity.getProcessInstanceId())).setAction("COMPLETE"); iYnjtTaskSendService.sendApprovedTask(Collections.singletonList(ynjtTaskDTO)); try { iYnjtTaskSendService.sendTasks(null, Long.parseLong(taskEntity.getTenantId()), taskEntity.getProcessInstanceId(), "P", taskInfos); }catch (Exception e){ LOGGER.error(taskEntity.getProcessInstanceId() + "审批后生成下一节点的待办推送失败:" + e.getMessage()); } } }
|
- onApplicationEvent方法中的参数为上面新建的事件类。
- 加上 @TransactionalEventListener 注解,TransactionPhase.AFTER_COMMIT 表示在上个事务提交之前再执行。
事件调用
在其它事务方法中调用即可,可实现当前方法事务提前后再 执行该事件监听的执行内容。
因此调用的方法必须是有事务的,即使用@Transactional
进行注解了,这样事务监听才会生效
1 2
| applicationEventPublisher.publishEvent(new TodoPushEvent(taskEntity,processTaskInfos));
|