首页 > 解决方案 > Spring Data REST 事件处理程序是否使用单独的数据库事务?

问题描述

Spring Data REST 具有以下事件处理程序,这些事件处理程序在 HTTP 请求(如 POST、PUT 等)上触发。

@RepositoryEventHandler(Author.class) 
public class AuthorEventHandler {
    Logger logger = Logger.getLogger("Class AuthorEventHandler");

    @HandleBeforeCreate
    public void handleAuthorBeforeCreate(Author author){
        logger.info("Inside Author Before Create....");

    }

    @HandleAfterCreate
    public void handleAuthorAfterCreate(Author author){
        logger.info("Inside Author After Create ....");

    }

}

我的问题是,如果我在@HandleBeforeCreate 中访问另一个数据库实体(例如Book)并对其进行修改,它会发生在单独的事务中还是会发生在与创建作者实体相同的事务中?

我已经检查了 Spring Data REST 文档,但那里没有提到。

标签: springspring-data-rest

解决方案


根据我的经验,这些处理程序是在主事务之外执行的。字面意思是“之前”和“之后”。关于“单独”事务 - 如果您将事件处理程序标记为@Transactional它将在其单独的事务中执行。


从聚合根发布域事件

如果您需要在主事务中执行一些额外的操作,您可以使用来自聚合根的发布事件在这种情况下,您应该从AbstractAggregateRoot扩展您的实体并向其添加一些注册适当事件的方法,例如:

@Entity
public class Model extends AbstractAggregateRoot {

   // entity stuff...

   public Model initExtraAction(SomeData payload) {
        registerEvent(new ExtraActionEvent(this, payload));
        return this;
   }
}

其中registerEventAbstractAggregateRoot方法,并且ExtraActionEvent是您的自定义事件,如下所示:

@Value
public class ExtraActionEvent {
    private Model model;
    private SomeData payload;
}

然后你可以实现一个普通的事件处理程序

@Service
public class EventHandler {

    @EventListener
    @Transactional(propagation = MANDATORY) // optional 
    public void handleExtraActionEvent (ExtraActionEvent e) {
        Model model = e.getModel();
        SomeData payload = e.getPayload();

        // Extra actions...
    }
}

如果您在调用 repo 的方法之前调用方法,它将在与主要事务(保存您的实体)相同的事务中被调用(以确保这将在同一事务中完成,您可以使用可选注释):initExtendActionsave @Transactional(propagation = MANDATORY)

modelRepo.save(model.initExtraAction(payload));

Spring Data REST项目中,我们可以initExtraAction在创建或更新实体之前调用“RepositoryEventHandler”中的方法:

@RepositoryEventHandler(Model.class) 
public class ModelEventHandler {

    @HandleBeforeCreate
    @HandleBeforeSave
    public void handleBeforeCreateOrSave(Model model){
        // Some manipulations...
        model.initExtraAction(...);
    }
}

AbstractAggregateRoot您可以在 Oliver Gierke Spring RestBucks演示项目中找到完整的使用示例。

附加信息:DDD 聚合和@DomainEvents


推荐阅读