spring - 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 文档,但那里没有提到。
解决方案
根据我的经验,这些处理程序是在主事务之外执行的。字面意思是“之前”和“之后”。关于“单独”事务 - 如果您将事件处理程序标记为@Transactional
它将在其单独的事务中执行。
从聚合根发布域事件
如果您需要在主事务中执行一些额外的操作,您可以使用来自聚合根的发布事件。在这种情况下,您应该从AbstractAggregateRoot扩展您的实体并向其添加一些注册适当事件的方法,例如:
@Entity
public class Model extends AbstractAggregateRoot {
// entity stuff...
public Model initExtraAction(SomeData payload) {
registerEvent(new ExtraActionEvent(this, payload));
return this;
}
}
其中registerEvent是AbstractAggregateRoot
方法,并且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 的方法之前调用方法,它将在与主要事务(保存您的实体)相同的事务中被调用(以确保这将在同一事务中完成,您可以使用可选注释):initExtendAction
save
@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
推荐阅读
- javascript - 如何通过 Rails 中的帖子 ID 在社交媒体上分享您博客中的帖子
- c++ - 从 C++ 列表中删除项目
- pyspark - 有没有类似的方法可以在pyspark中复制熊猫的“qcut”功能?
- c# - 按钮单击事件上的 HTML 表日期松动
- ios - 无法使用 NSKeyedArchiver 保存我的模型
- deep-learning - 张量板的准确度/训练和损失/训练图
- php - 在 htcaccess 中重写 URL
- php - Web API 发送的数据没有价值
- firebase - 即使我修改了某些字段,我如何才能从 Firestore 中仅获取一次数据?
- javascript - 使用Angular中的下拉菜单显示/隐藏div元素?