当前位置: 首页 > news >正文

专业网站建设代理同城信息商家的网站开发

专业网站建设代理,同城信息商家的网站开发,陈村网站设计,引流推广营销使用背景 在业务中,经常会有这样的需求,在数据库事务提交之后,发送异步消息或者进行其他的事务操作。 例如当用户注册成功之后,发送激活码,如果用户注册后就执行发送激活码,但是在用户保存时出现提交事务…

使用背景

在业务中,经常会有这样的需求,在数据库事务提交之后,发送异步消息或者进行其他的事务操作。

例如当用户注册成功之后,发送激活码,如果用户注册后就执行发送激活码,但是在用户保存时出现提交事务异常,数据库进行回滚,用户实际没有注册成功,但是用户却收到了激活码,此时,正确的是应该在用户注册保存事务提交完成之后,然后发送激活码。

标题复制10行,并且每行大于10个字符【Spring事务】Spring事务事件控制,解决业务异步操作【Spring事务】Spring事务事件控制,解决业务异步操作,并且每行大于10个字符【Spring事务】Spring事务事件控制,解决业务异步操作

使用注解@TransactionalEventListener

demo展示

事务监听器

@Component
public class TransactionListener {@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)public void handler(TransactionEvent transactionEvent) {System.out.println(transactionEvent.getSource());}
}

业务代码

@Override
@Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
public void saveUser() {User user = new User();userMapper.insert(user);eventPublisher.publishEvent(newTransactionEvent("事务提交后发布事件1"));
}
标题复制10行,并且每行大于10个字符【Spring事务】Spring事务事件控制,解决业务异步操作【Spring事务】Spring事务事件控制,解决业务异步操作,并且每行大于10个字符【Spring事务】Spring事务事件控制,解决业务异步操作

源码解析

EventListenerMethodProcessor

EventListenerMethodProcessor用来解析带有带有@EventListener注解的方法。遍历类上的方法,判断工厂是否支持,用对应的工厂生成监听器。

	private void processBean(final String beanName, final Class<?> targetType) {if (!this.nonAnnotatedClasses.contains(targetType) &&AnnotationUtils.isCandidateClass(targetType, EventListener.class) &&!isSpringContainerClass(targetType)) {//...if (CollectionUtils.isEmpty(annotatedMethods)) {//...}else {// Non-empty set of methodsConfigurableApplicationContext context = this.applicationContext;Assert.state(context != null, "No ApplicationContext set");List<EventListenerFactory> factories = this.eventListenerFactories;Assert.state(factories != null, "EventListenerFactory List not initialized");for (Method method : annotatedMethods.keySet()) {for (EventListenerFactory factory : factories) {if (factory.supportsMethod(method)) {Method methodToUse = AopUtils.selectInvocableMethod(method, context.getType(beanName));ApplicationListener<?> applicationListener =factory.createApplicationListener(beanName, targetType, methodToUse);if (applicationListener instanceof ApplicationListenerMethodAdapter) {((ApplicationListenerMethodAdapter) applicationListener).init(context, this.evaluator);}context.addApplicationListener(applicationListener);break;}}}if (logger.isDebugEnabled()) {logger.debug(annotatedMethods.size() + " @EventListener methods processed on bean '" +beanName + "': " + annotatedMethods);}}}}

TransactionalEventListenerFactory仅支持TransactionalEventListener注解,生成ApplicationListenerMethodTransactionalAdapter的对象。

public class TransactionalEventListenerFactory implements EventListenerFactory, Ordered {private int order = 50;public TransactionalEventListenerFactory() {}public void setOrder(int order) {this.order = order;}public int getOrder() {return this.order;}public boolean supportsMethod(Method method) {return AnnotatedElementUtils.hasAnnotation(method, TransactionalEventListener.class);}public ApplicationListener<?> createApplicationListener(String beanName, Class<?> type, Method method) {return new ApplicationListenerMethodTransactionalAdapter(beanName, type, method);}
}

AbstractTransactionManagementConfiguration会引入TransactionalEventListenerFactory

    @Bean(name = {"org.springframework.transaction.config.internalTransactionalEventListenerFactory"})@Role(2)public static TransactionalEventListenerFactory transactionalEventListenerFactory() {return new TransactionalEventListenerFactory();}
标题复制10行,并且每行大于10个字符【Spring事务】Spring事务事件控制,解决业务异步操作【Spring事务】Spring事务事件控制,解决业务异步操作,并且每行大于10个字符【Spring事务】Spring事务事件控制,解决业务异步操作

ApplicationListenerMethodTransactionalAdapter

发布事件,主要是创建了TransactionSynchronization,注册到了TransactionSynchronizationManager

    public void onApplicationEvent(ApplicationEvent event) {if (TransactionSynchronizationManager.isSynchronizationActive() && TransactionSynchronizationManager.isActualTransactionActive()) {TransactionSynchronization transactionSynchronization = this.createTransactionSynchronization(event);TransactionSynchronizationManager.registerSynchronization(transactionSynchronization);} else if (this.annotation.fallbackExecution()) {if (this.annotation.phase() == TransactionPhase.AFTER_ROLLBACK && this.logger.isWarnEnabled()) {this.logger.warn("Processing " + event + " as a fallback execution on AFTER_ROLLBACK phase");}this.processEvent(event);} else if (this.logger.isDebugEnabled()) {this.logger.debug("No transaction is active - skipping " + event);}}
标题复制10行,并且每行大于10个字符【Spring事务】Spring事务事件控制,解决业务异步操作【Spring事务】Spring事务事件控制,解决业务异步操作,并且每行大于10个字符【Spring事务】Spring事务事件控制,解决业务异步操作

事务提交

TransactionSynchronizationUtils#invokeAfterCompletion,事务提交会遍历TransactionSynchronization执行afterCompletion方法

    public static void invokeAfterCompletion(@Nullable List<TransactionSynchronization> synchronizations, int completionStatus) {if (synchronizations != null) {Iterator var2 = synchronizations.iterator();while(var2.hasNext()) {TransactionSynchronization synchronization = (TransactionSynchronization)var2.next();try {synchronization.afterCompletion(completionStatus);} catch (Throwable var5) {logger.error("TransactionSynchronization.afterCompletion threw exception", var5);}}}

ApplicationListenerMethodTransactionalAdapter.TransactionSynchronizationEventAdapter#afterCompletion,调用事件监听器的processEvent方法,会反射调用被@TransactionalEventListener修饰的方法。

        public void afterCompletion(int status) {if (this.phase == TransactionPhase.AFTER_COMMIT && status == 0) {this.processEvent();} else if (this.phase == TransactionPhase.AFTER_ROLLBACK && status == 1) {this.processEvent();} else if (this.phase == TransactionPhase.AFTER_COMPLETION) {this.processEvent();}}protected void processEvent() {this.listener.processEvent(this.event);}
标题复制10行,并且每行大于10个字符【Spring事务】Spring事务事件控制,解决业务异步操作【Spring事务】Spring事务事件控制,解决业务异步操作,并且每行大于10个字符【Spring事务】Spring事务事件控制,解决业务异步操作

使用TransactionSynchronizationManager TransactionSynchronizationAdapter

demo展示

@Autowired
private UserDao userDao;
@Autowired
private JmsProducer jmsProducer;public User saveUser(User user) {// 保存用户userDao.save(user);final int userId = user.getId();// 兼容无论是否有事务if(TransactionSynchronizationManager.isActualTransactionActive()) {TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {@Overridepublic void afterCommit() {jmsProducer.sendEmail(userId);}});} else {jmsProducer.sendEmail(userId);}
}
标题复制10行,并且每行大于10个字符【Spring事务】Spring事务事件控制,解决业务异步操作【Spring事务】Spring事务事件控制,解决业务异步操作,并且每行大于10个字符【Spring事务】Spring事务事件控制,解决业务异步操作

在这里插入图片描述

标题复制10行,并且每行大于10个字符【Spring事务】Spring事务事件控制,解决业务异步操作【Spring事务】Spring事务事件控制,解决业务异步操作,并且每行大于10个字符【Spring事务】Spring事务事件控制,解决业务异步操作

http://www.yayakq.cn/news/101248/

相关文章:

  • 网站开发时自适应今东外贸人才网
  • 怎么0成本做网站dw做网站的流程
  • mysql网站后台管理系统下载福建省网站建设
  • 高端网站建设需要的人员配备北京市门户网站
  • 新郑市网站建设做网站百度云
  • 简洁 网站模板WordPress 布局 企业网站
  • 绛县做网站春哥 响应式网站建设
  • 怎么知道网站是哪个公司做的阿里巴巴外贸平台费用
  • 电白区住房和城乡建设部门户网站销售网站怎么做的
  • 济南网站制作培训班浙江城乡与住房建设部网站
  • 主机宝 建设网站国外WordPress小说主题
  • 网站首页设计要求企业网站管理系统登陆
  • 网站建设什么专业建设网站经营范围
  • 网站的营销功能做公司网站需要注意什么
  • 升级网站订阅号如何申请
  • 国外购物网站赏析大连网站设计费用
  • 网站开发需求文档模板带er图网站关键词进前三
  • 网站权重是怎样进行传递的网站解析慢 优化
  • 网站开发方向 英语翻译一个人在线观看播放视频
  • 网站建设营销词西安是哪个省属于哪个市
  • 网站建设招投标大连百度推广哪家好
  • 网站架构策划外贸免费建设网站
  • php网站301重定向网站建设做网站费用
  • 宜昌本地网站东莞网络营销外包价格
  • 上海买二手房做哪个网站好wordpress themes.php
  • 做专业慢摇的网站发布建设网站
  • 网站制作网免费大邑县建设银行网站
  • 网站首页轮播图怎么做职工素质建设 网站
  • 网站设计排行榜凡科网站建设推广
  • 网站怎么做七牛云加速公司怎么做网站需要多少钱