支持事务关联的 Java 或 Spring async TaskExeuctor?

标签 java spring

我正在尝试使用一个 @TransactionalEventListener(Spring 4.3),它将在事务完成后运行一个事件。

但是,我有自己的 ApplicationEventMulticaster,我正在构建并使用 ThreadPoolTask​​Executor

SimpleApplicationEventMulticaster 状态的文档:

    /**
     * Set a custom executor (typically a {@link org.springframework.core.task.TaskExecutor})
     * to invoke each listener with.
     * <p>Default is equivalent to {@link org.springframework.core.task.SyncTaskExecutor},
     * executing all listeners synchronously in the calling thread.
     * <p>Consider specifying an asynchronous task executor here to not block the
     * caller until all listeners have been executed. However, note that asynchronous
     * execution will not participate in the caller's thread context (class loader,
     * transaction association) unless the TaskExecutor explicitly supports this.
     * @see org.springframework.core.task.SyncTaskExecutor
     * @see org.springframework.core.task.SimpleAsyncTaskExecutor
     */
    public void setTaskExecutor(Executor taskExecutor) {
        this.taskExecutor = taskExecutor;
    }

但是,我无法找到事务感知的 Async TaskExecutor。 Java 生态系统中是否已经存在这样的东西?

目前,我的事件从未运行过,因为 ThreadPoolTask​​Executor 不了解事务,因此它始终认为没有当前事务 - 忽略事件监听器。

最佳答案

不,目前稳定的 TaskExecutor 将与 spring 管理的事务一起工作,目前 Spring 通过 ThreadLocals 将事务绑定(bind)到线程。

但您只需在 @TransactionalEventListener 监听器方法上添加 @Async 注释,即可轻松地在代码中使用异步 @TransactionalEventListener。请记住,仅当在事务边界及其后提交阶段调用发布者时,Spring 才会将事件发布给监听器,但事务已完成,因此对象处于分离状态。

假设您需要从事务中发布事件

@Service
public class Service {

        @Autowired
        private SomeRepository someRepository;

        @Autowired
        private ApplicationEventPublisher applicationEventPublisher;

        @Transactional
        public void create(SomeEntity entity) {
            someRepository.save(entity);
            SomeEntityCreatedEvent event = new SomeEntityCreatedEvent();
            event.entity = entity;
            applicationEventPublisher.publishEvent(event);
        }

        public static final class SomeEntityCreatedEvent {
            private SomeEntity entity;

            public SomeEntity getSomeEntity() {
               return entity;
            }
        }
}

监听器将获得具有已分离实体的事件,因此不会将其更改传播到数据存储区。

@Component
public class UpdatesListener {

    @Async // here you can controll the task executor which needs to take care of this thread
    @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
    public void handleCustom(Service.SomeEntityCreatedEvent event) {
        // here entity is deatached
        SomeEntity entity = event.getSomeEntity();
        System.out.println("Created some entity with id" + entity.getId());
    }

}

啊,不要覆盖 SimpleApplicationEventMulticaster 上的默认 SyncTaskExecutor,而是在监听器上使用 @Async

关于支持事务关联的 Java 或 Spring async TaskExeuctor?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60976077/

相关文章:

java - 为什么我要为String数组获取java.lang.NullPointerException?

java - Java 中的 BorderLayout() 问题

java - 从 ButtonGroup() 返回值

java - 使用哪个 Java 线程池执行器来轻松调整池大小?

java - 带有动态参数的自定义注释

java - GsonConverter 未解决

java - 应用程序编程中的线程

javascript - 如何使用ajax从jsp中检索 Controller 返回的值

java - Spring MVC 模型绑定(bind)不适用于非公共(public)成员

java - 有没有Spring,性能有没有提升