Spring Data REST 事件处理程序是否使用单独的数据库事务? [英] Does Spring Data REST event hanlders use separate database transactions?

查看:43
本文介绍了Spring Data REST 事件处理程序是否使用单独的数据库事务?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Spring Data REST has the following Event handlers which are fired on HTTP requests like POST, PUT etc.

@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 并对其进行修改,它会发生在单独的事务中还是会发生在与创建 Author 实体相同的事务中?

My question is if I access another database entity, eg.Book, within @HandleBeforeCreate and modify it, would it occur in a separate transaction or will it occur in the same transaction as the creation of the Author entity?

我已经查看了 Spring Data REST 文档,但那里没有提到它.

I already check the Spring Data REST docs but it is not mentioned there.

推荐答案

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

From my experience, those handlers are performed beyond the main transaction. Literally 'before' and 'after' it. About 'separate' transaction - if you mark your event handler as @Transactional it will be executed in its individual transaction.

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

If you need to perform some extra actions within the main transaction you can use publishing events from the aggregate root. In this case, you should extend your entity from AbstractAggregateRoot and add to it some methods that register appropriate events, for example:

@Entity
public class Model extends AbstractAggregateRoot {

   // entity stuff...

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

where registerEventAbstractAggregateRoot 方法,ExtraActionEvent 是您的自定义事件,如下所示:

where registerEvent is the AbstractAggregateRoot method, and ExtraActionEvent is your custom event, like the folowing:

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

然后就可以实现一个普通的事件处理器

Then you can implement an ordinary event handler

@Service
public class EventHandler {

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

        // Extra actions...
    }
}

如果您调用 initExtendAction 方法在调用save 存储库的方法(为了确保这将在同一事务中完成,您可以使用 可选 @Transactional(propagation = MANDATORY) 注释):

that will be called in the same transaction as the main one (which saves your entity) if you call initExtendAction method before invoking the save method of your repo (to make sure that this will be done in the same transaction you can use an optional @Transactional(propagation = MANDATORY) annotation):

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

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

In the Spring Data REST project we can call initExtraAction method in the 'RepositoryEventHandler' before the entity will be created or updated:

@RepositoryEventHandler(Model.class) 
public class ModelEventHandler {

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

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

You can find a full example of using AbstractAggregateRoot in the Oliver Gierke Spring RestBucks demo project.

附加信息:DDD 聚合和@DomainEvents

这篇关于Spring Data REST 事件处理程序是否使用单独的数据库事务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆