我在一个微服务架构中使用Spring Data JPA。我在MyService中有一个简单的保存方法(实际上它使用泛型,但是为了简单起见,让我们假设这是等价的),它位于两个应用程序之间的共享库中:
@SneakyThrows
@Transactional
public DTO save(DTO dto) {
MyEntity entity = Optional
.ofNullable(dto.getId())
.flatMap(repository::findById)
.orElse(new MyEntity());
modelMapper.map(dto, entity);
return modelMapper.map(repository.save(entity), DTO.class);
}
其中repository是一个JpaRepository。到目前为止,一切都很顺利。我有两个Spring应用程序;应用程序A执行一些操作,保存实体,然后调用应用程序B,方式如下:
DTO dto = myService.findById(id);
//modifying the dto...
myService.save(dto);
myFeignClient.callApplicationB(id);
应用程序B背后的结构类似(查找、编辑、保存),但在数据库上记录跟踪(我使用SQL Server,2016或2019的行为相同),我看到第二次更新(应用程序B的更新)在“第一次”更新(应用程序A的更新)之前执行。我是否遗漏了明显的配置,或者我应该在其他地方搜索该问题?
1条答案
按热度按时间brgchamk1#
问题是以下@交易陷阱:使用保存方法的服务用
@Transactional
注解,因此所有方法都是事务性的,如下面的代码片段所示我用下面的方法修改了代码
另一种解决方案是,如果希望保持相同的事务边界,则将整个数据传递给应用程序B,并将其修改后返回:
编辑:我将试着澄清交易背后的逻辑。旧的逻辑如下:
在解决方案中,事务A1在调用应用程序B之前关闭,因此A所做的更改在B所做的任何更改之前提交。