开始一个仅用于保存的交易
Start a transaction for saving only
我想知道在以下情况下推荐的处理方式是什么:
- 假设我有一个
ReportService
负责生成报告、上传报告、发送电子邮件并将其保存在数据库中。
- 在数据库中保存时,它会更新很多实体,我想回滚整个事情以防万一。
所以它会是这样的:
@Service
public class ReportService {
public void generateReport() {
var entities = entityRepository.findEntities();
var file = getReportData(entities);
var url = uploadFile(file);
sendEmail(url);
// If something goes wrong while save on entity, roll back everything
for (var e : entities) {
entityRepository.save(e);
}
}
}
所以我知道我有的选择是:
- 用
@Transactional
注释该方法:我认为这不是一个好主意,因为我们会将 HTTP 请求和工作负载与数据库事务混合在一起
- 创建一个全新的服务,比如
ReportSavingService
,并有一个方法来只保存那些实体:我认为这会起作用,但对我来说有一个处理相同业务逻辑的特定服务似乎很奇怪我已经有一个服务,只是为了保存它...
我想知道这些是否是我们处理 Spring 数据的解决方案,或者是否有一种简单的方法可以执行以下操作:
// ...
sendEmail(url);
// If something goes wrong while save on entity, roll back everything
database.beginTransaction();
for (var e : entities) {
entityRepository.save(e);
}
database.commit();
我知道我们有这种控制,直接使用 EntityManager
,但我不能将它与 Spring 数据的存储库方法混合......我可以吗?
您要找的是 TransactionTemplate
@Autowired
TransactionTemplate tx;
// ...
tx.execute(__ -> {
for (var e : entities) {
entityRepository.save(e);
}
}
我同意@crizzis 的评论,即设计似乎有些错误,但我认为这与问题无关。
我想知道在以下情况下推荐的处理方式是什么:
- 假设我有一个
ReportService
负责生成报告、上传报告、发送电子邮件并将其保存在数据库中。 - 在数据库中保存时,它会更新很多实体,我想回滚整个事情以防万一。
所以它会是这样的:
@Service
public class ReportService {
public void generateReport() {
var entities = entityRepository.findEntities();
var file = getReportData(entities);
var url = uploadFile(file);
sendEmail(url);
// If something goes wrong while save on entity, roll back everything
for (var e : entities) {
entityRepository.save(e);
}
}
}
所以我知道我有的选择是:
- 用
@Transactional
注释该方法:我认为这不是一个好主意,因为我们会将 HTTP 请求和工作负载与数据库事务混合在一起 - 创建一个全新的服务,比如
ReportSavingService
,并有一个方法来只保存那些实体:我认为这会起作用,但对我来说有一个处理相同业务逻辑的特定服务似乎很奇怪我已经有一个服务,只是为了保存它...
我想知道这些是否是我们处理 Spring 数据的解决方案,或者是否有一种简单的方法可以执行以下操作:
// ...
sendEmail(url);
// If something goes wrong while save on entity, roll back everything
database.beginTransaction();
for (var e : entities) {
entityRepository.save(e);
}
database.commit();
我知道我们有这种控制,直接使用 EntityManager
,但我不能将它与 Spring 数据的存储库方法混合......我可以吗?
您要找的是 TransactionTemplate
@Autowired
TransactionTemplate tx;
// ...
tx.execute(__ -> {
for (var e : entities) {
entityRepository.save(e);
}
}
我同意@crizzis 的评论,即设计似乎有些错误,但我认为这与问题无关。