前段
typeormにてsave後にfindした値を戻り値に使いたいケースがあった。
DBの構成がmaster/slaveになっているためレプリケーションに若干のタイムラグがあった(100msecとか)。
そのためsaveした内容がslaveに反映される前にslaveからfindしてしまい、更新前の値を返却してしまうというケースが発生した。
内容
transactionを利用することでmasterへのsave, masterからのfindが実行されることになりこの問題は解決した。
以下サンプルコード
- before
async updateHoge(params: { id: string } & Partial<HogeEntity>): Promise<HogeEntity> {
const existed = await this.hogeRepository.findOne({ id: params.id });
if (!existed) {
throw new Error(`invalid id: ${params.id}`);
}
const updatedParams = {
...existed,
...params,
};
await this.hogeRepository.save(updatedParams);
const updated = await this.hogeRepository.findOne({ id: params.id });
if (!updated) {
throw new Error(`invalid id: ${params.id}`);
}
return updated;
}
- after
@Transaction('test')
async updateHoge(
params: { id: string } & Partial<HogeEntity>,
@TransactionRepository(HogeEntity) hogeRepository?: Repository<HogeEntity>,
): Promise<HogeEntity> {
if (hogeRepository === undefined) {
throw new Error('Transaction repository does not exist');
}
const existed = await hogeRepository.findOne({ id: params.id });
if (!existed) {
throw new Error(`invalid id: ${params.id}`);
}
const updatedParams = {
...existed,
...params,
};
await hogeRepository.save(updatedParams);
const updated = await hogeRepository.findOne({ id: params.id });
if (!updated) {
throw new Error(`invalid id: ${params.id}`);
}
return updated;
}