문제상황
- Transaction -> [Service[Writer(합류)]]
- Mandatory로 인해 Service 트랜잭션에 합류되어 최종 반영은 서비스 이후가 됌
- 즉, ModifiedDate는 트랜잭션이 커밋되는 순간에 반영
- 그렇게 되면 Service에서 Info로 updated_at을 내보낼시 변경시간은 반영이 되지 않는 TOCTOU 문제가 생김
GuildService {
@Transactional
public GuildResult.Info changePolicy(Long playerId, Long id, GuildCommand.ChangePolicy command) {
Guild guild = guildReader.getOwned(playerId, id);
return GuildResult.Info.from(guildWriter.changePolicy(guild, command));
}
}
@Transactional(propagation = Propagation.MANDATORY)
GuildWriter {
public Guild changePolicy(Guild guild, GuildCommand.Kick c) {
if (c.visibility() != null) {
guild.changeVisibility(GuildVisibility.valueOf(c.visibility()));
}
if (c.joinPolicy() != null) {
guild.changeJoinPolicy(GuildJoinPolicy.valueOf(c.joinPolicy()));
}
if (c.maxMembers() > 0) {
guild.changeMaxMembers(c.maxMembers());
}
return guild;
}
}
해결방안
- 변경감지시 Auditing을 기본적으로 노출하지 않음
- 즉, No Content 반환 및 변경된 데이터로 id 조회 API 제공
-
- 빠른 반영 필요시 TimeProvider 등 글로벌 툴로 만들어 Clock을 통해 메서드화 후 직접 주입
- 반영전 타임 반환 가능해짐