1.Spring版本与适用范围

版本要求:Spring4.2+

适用范围:SpringBoot的数据库事务的回滚/提交等,其中文件I/O类事件待进一步确认

2.实现方式

基于 ApplicationEventPublisher的事件发布机制与 @TransactionEventListener的事件监听机制。

2.1 @TransactionEventListener 注解简介

@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@EventListener 
public @interface TransactionalEventListener {
	// 注解取值有:BEFORE_COMMIT、AFTER_COMMIT、AFTER_ROLLBACK、AFTER_COMPLETION
	// 需要注意的是:AFTER_COMMIT + AFTER_COMPLETION是可以同时生效的
	TransactionPhase phase() default TransactionPhase.AFTER_COMMIT;

	// 若没有事务的时候,对应的event是否已经执行  默认值为false表示  没事务就不执行了
	boolean fallbackExecution() default false;

	@AliasFor(annotation = EventListener.class, attribute = "classes")
	Class<?>[] value() default {};
	//支持按照类型类进行匹配(作用待验证)
	@AliasFor(annotation = EventListener.class, attribute = "classes")
	Class<?>[] classes() default {};
    //支持按照SpEL表达式进行匹配
	String condition() default "";
}

2.2 自定义监听事件

//事件需要继承ApplicationEvent ,SampleDistributioDTO为事件中需要在多种状态下传递的参数,如事件ID
//或者订单ID
public class SampleDistributionEvent extends ApplicationEvent {
   public SampleDistributionEvent(SampleDistributioDTO sampleDistributioDTO){
     super(sampleDistributioEntity);
  }
}

2.3 启用事件监听

@Component
public class SampleDistributionTransactionEventListener {
    //此处的入参为2.2中创建的自定义监听事件
    @TransactionalEventListener(phase = TransactionPhase.AFTER_ROLLBACK)
    public void afterRollback(SampleDistributionEvent event) {
        System.out.println("after rollback, id: " + event.getSource());
    }
    @TransactionalEventListener(phase = TransactionPhase.BEFORE_COMMIT)
    public void beforeCommit(SampleDistributionEvent event) {
        System.out.println("before commit, id: " + event.getSource());
    }

    @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
    public void afterCommit(SampleDistributionEvent event) {
        System.out.println("after commit, id: " + event.getSource());
    }

    @TransactionalEventListener(phase = TransactionPhase.AFTER_COMPLETION)
    public void afterCompletion(SampleDistributionEvent event) {
        System.out.println("after completion, id: " + event.getSource());
    }
}

2.4 发布事件监听(在数据库事务中)

@Service
public class TransTestService {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private ApplicationEventPublisher publisher;

    @Transactional
    public String testTrans() {
        SampleDistributioEntity sampleDistributioEntity = new SampleDistributioEntity();
        sampleDistributioEntity.setBatchNo("1111");
        publisher.publishEvent(new SampleDistributionEvent(sampleDistributioEntity));
        jdbcTemplate.execute("your sql");
        return "1";
    }
}

注意事项:
publishEvent 一定要放在execute 函数之前,特别是有多个SQL脚本时,防止部分失败,导致直接抛出异常从而会导致监听函数无法监听到回滚事件。

2.5 参考资料

https://www.cnblogs.com/AIPAOJIAO/p/9825771.html

https://blog.csdn.net/f641385712/article/details/91897175


标题:SpringBoot 事务事件监听(如事务提交&事务回滚)实现方式
作者:TravelEngineers
地址:https://www.mycitymemory.com/articles/2020/05/19/1589861412726.html
版权声明:转载请注明博文地址,尊重作者劳动成果。
作者简介:坐标魔都,一枚爱旅行爱摄影的攻城狮。愿攻城拔寨的路上,你不用996,也不再孤单,加油。

添加新评论