在业务中使用发布/订阅模式,如何处理和事务之间的关系?


假设业务场景如:用户发布博文,文章需要做索引供全文检索,记录操作日志以及计数功能(个人博客总数,某分类下博客数);其中如果计数服务出现异常事务应该回滚,索引和日志出异常应不影响博客保存。

   
  @Transactional(propagation=Propagation.REQUIRED)
  
public Blog save(Blog blog) {

  //持久化,可能出现数据库异常,如主键约束,字段过大
  dao.save(blog);
  //发布 新增博客 事件,订阅者有 索引服务,日志服务,计数服务
  fireEvent(blogEvent);//可同步或异步处理事件

return blog;
}

问题:
使用spring控制事务,当事务commit时,才可能抛出底层异常;但此时fireEvent方法已经执行完成了;结果是博文并未保存但触发了索引、日志服务,有什么好的方法处理这种情况吗?
我想到方法是:在之上在加一层代理,fireEvent移除至事务之外,

   
  public Blog proxySave(Blog blog){
  
//事务层save
save(blogEvent); //有影响事务 计数服务 放在里面
  
  //发布 新增博客 事件,订阅者有 索引服务,日志服务
fireEvent(blogEvent);
return blog;
}

这样做不好之处,多增加一层增加码量;fireEvent事件可以做成异步队列,是否可以借助filter 在chain.doFilter(request, response)后,判断当前线程事务是否提交,在决定fireEvent 中异步订阅者是否发布执行?不知各位有什么好的意见,类似这种业务如何处理?

架构设计 设计模式

奈何de彼岸 11 years, 4 months ago

Your Answer