我需要将2个不同的实体插入到2个不同的表中,使用同一个事务。如果第二个插入失败,第一个插入应该被回滚。
有没有一种比较好的方式来实现这个需求?
伪代码:
start tx
repo1.save(myEntity);
repo2.save(anotherEntity);
try commit
我知道你可以利用@Transactional
,但仅限于方法级别?
我需要将2个不同的实体插入到2个不同的表中,使用同一个事务。如果第二个插入失败,第一个插入应该被回滚。
有没有一种比较好的方式来实现这个需求?
伪代码:
start tx
repo1.save(myEntity);
repo2.save(anotherEntity);
try commit
我知道你可以利用@Transactional
,但仅限于方法级别?
您需要检查是否已经设置了 autocommit = false。
将保存操作包装到一个服务方法中,并将其标记为 @Transactional
。但如果您使用的是 save()
自定义方法,请检查是否将其保存为标记为 @Transactional
,并具有传播级别 required_new 或 nested。如果需要,您可以在保存服务方法中使用 REQUIRES_NEW
,使该服务方法与其他事务无关。
同时,您可以将其包装在 TransactionTemplate 中。
@Autowired
private TransactionTemplate transactionTemplate;
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
public void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
repo1.save(myEntity);
repo2.save(anotherEntity);
});
通常在仓库方法周围声明 @Transactional
是错误的想法。
仓库只是用于访问域实体。业务逻辑通常涉及多个域实体之间的协作。
你的架构中应该有一个层来组合业务逻辑。这通常对应于向外部公开的服务。
这通常是您应该设置事务边界的地方。通常是一个控制器或服务方法。
操作步骤:
@Transactional
注释。 - M. Deinum