Spring Data REST 事件处理程序是否使用单独的数据库事务?
Does Spring Data REST event hanlders use separate database transactions?
Spring Data REST 具有以下事件处理程序,这些事件处理程序在 POST、PUT 等 HTTP 请求时触发
@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 中访问另一个数据库实体 eg.Book 并修改它,它会发生在单独的事务中还是会发生在与创建作者实体相同的事务中?
我已经检查了 Spring 数据 REST 文档,但那里没有提到它。
根据我的经验,这些处理程序是在主事务之外执行的。字面意思是 'before' 和 'after' 吧。关于 'separate' 事务 - 如果您将事件处理程序标记为 @Transactional
,它将在其单独的事务中执行。
从聚合根发布域事件
如果您需要在主事务中执行一些额外的操作,您可以使用 publishing events from the aggregate root. In this case, you should extend your entity from 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...
}
}
如果您在之前[=]调用initExtendAction
方法,将在相同事务中调用作为主事务(它保存您的实体) 50=] 调用你的 repo 的 save
方法(为了确保这将在同一个事务中完成,你可以使用 optional @Transactional(propagation = MANDATORY)
注释):
modelRepo.save(model.initExtraAction(payload));
在 Spring Data REST 项目中,我们可以在创建或更新实体之前调用 'RepositoryEventHandler' 中的 initExtraAction
方法:
@RepositoryEventHandler(Model.class)
public class ModelEventHandler {
@HandleBeforeCreate
@HandleBeforeSave
public void handleBeforeCreateOrSave(Model model){
// Some manipulations...
model.initExtraAction(...);
}
}
您可以在 Oliver Gierke Spring RestBucks 演示项目中找到使用 AbstractAggregateRoot
的完整示例。
Spring Data REST 具有以下事件处理程序,这些事件处理程序在 POST、PUT 等 HTTP 请求时触发
@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 中访问另一个数据库实体 eg.Book 并修改它,它会发生在单独的事务中还是会发生在与创建作者实体相同的事务中?
我已经检查了 Spring 数据 REST 文档,但那里没有提到它。
根据我的经验,这些处理程序是在主事务之外执行的。字面意思是 'before' 和 'after' 吧。关于 'separate' 事务 - 如果您将事件处理程序标记为 @Transactional
,它将在其单独的事务中执行。
从聚合根发布域事件
如果您需要在主事务中执行一些额外的操作,您可以使用 publishing events from the aggregate root. In this case, you should extend your entity from 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...
}
}
如果您在之前[=]调用initExtendAction
方法,将在相同事务中调用作为主事务(它保存您的实体) 50=] 调用你的 repo 的 save
方法(为了确保这将在同一个事务中完成,你可以使用 optional @Transactional(propagation = MANDATORY)
注释):
modelRepo.save(model.initExtraAction(payload));
在 Spring Data REST 项目中,我们可以在创建或更新实体之前调用 'RepositoryEventHandler' 中的 initExtraAction
方法:
@RepositoryEventHandler(Model.class)
public class ModelEventHandler {
@HandleBeforeCreate
@HandleBeforeSave
public void handleBeforeCreateOrSave(Model model){
// Some manipulations...
model.initExtraAction(...);
}
}
您可以在 Oliver Gierke Spring RestBucks 演示项目中找到使用 AbstractAggregateRoot
的完整示例。