Skip to content

Commit 72d1bb7

Browse files
committed
refactor: redis 트랜젝션 방식 변경
1 parent 7aa8272 commit 72d1bb7

File tree

3 files changed

+64
-43
lines changed

3 files changed

+64
-43
lines changed

apps/backend/src/redis/redis.service.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ export type RedisNode = {
1818
};
1919

2020
export type RedisEdge = {
21-
fromNode: number;
22-
toNode: number;
23-
type: 'add' | 'delete';
21+
fromNode?: number;
22+
toNode?: number;
23+
type?: 'add' | 'delete';
2424
};
2525

2626
@Injectable()

apps/backend/src/tasks/tasks.service.ts

Lines changed: 58 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,16 @@ import { InjectDataSource } from '@nestjs/typeorm';
1111
import { Page } from '../page/page.entity';
1212
import { Node } from '../node/node.entity';
1313
import { Edge } from '../edge/edge.entity';
14+
import { Inject } from '@nestjs/common';
15+
import Redis from 'ioredis';
16+
17+
const REDIS_CLIENT_TOKEN = 'REDIS_CLIENT';
1418

1519
@Injectable()
1620
export class TasksService {
1721
private readonly logger = new Logger(TasksService.name);
1822
constructor(
19-
private readonly redisService: RedisService,
23+
@Inject(REDIS_CLIENT_TOKEN) private readonly redisClient: Redis,
2024
@InjectDataSource() private readonly dataSource: DataSource,
2125
) {}
2226

@@ -25,9 +29,13 @@ export class TasksService {
2529
this.logger.log('스케줄러 시작');
2630
// 시작 시간
2731
const startTime = performance.now();
28-
const pageKeys = await this.redisService.getAllKeys('page:*');
29-
const nodeKeys = await this.redisService.getAllKeys('node:*');
30-
const edgeKeys = await this.redisService.getAllKeys('edge:*');
32+
33+
const pageKeys = await this.redisClient.keys('page:*');
34+
const nodeKeys = await this.redisClient.keys('node:*');
35+
const edgeKeys = await this.redisClient.keys('edge:*');
36+
// const pageKeys = await this.redisService.getAllKeys('page:*');
37+
// const nodeKeys = await this.redisService.getAllKeys('node:*');
38+
// const edgeKeys = await this.redisService.getAllKeys('edge:*');
3139

3240
Promise.allSettled([
3341
...pageKeys.map(this.migratePage.bind(this)),
@@ -51,7 +59,11 @@ export class TasksService {
5159
}
5260

5361
async migratePage(key: string) {
54-
const redisData = (await this.redisService.get(key)) as RedisPage;
62+
const data = await this.redisClient.hgetall(key);
63+
const redisData = Object.fromEntries(
64+
Object.entries(data).map(([field, value]) => [field, value]),
65+
) as RedisPage;
66+
// const redisData = (await this.redisClient.hgetall(key)) as RedisPage;
5567
// 데이터 없으면 오류
5668
if (!redisData) {
5769
throw new Error(`redis에 ${key}에 해당하는 데이터가 없습니다.`);
@@ -71,6 +83,7 @@ export class TasksService {
7183

7284
// 트랜잭션 시작
7385
const queryRunner = this.dataSource.createQueryRunner();
86+
const redisRunner = this.redisClient.multi();
7487
try {
7588
await queryRunner.startTransaction();
7689

@@ -81,20 +94,23 @@ export class TasksService {
8194
await pageRepository.update(pageId, updateData);
8295

8396
// redis에서 데이터 삭제
84-
await this.redisService.delete(key);
97+
redisRunner.del(key);
98+
// await this.redisService.delete(key);
8599

86100
// 트랜잭션 커밋
87101
await queryRunner.commitTransaction();
102+
await redisRunner.exec();
88103
} catch (err) {
89104
// 실패하면 postgres는 roll back하고 redis의 값을 살린다.
90105
this.logger.error(err.stack);
91106
await queryRunner.rollbackTransaction();
92-
updateData.title &&
93-
(await this.redisService.setField(key, 'title', updateData.title));
94-
updateData.content &&
95-
(await this.redisService.setField(key, 'content', JSON.parse(content)));
96-
updateData.emoji &&
97-
(await this.redisService.setField(key, 'emoji', updateData.emoji));
107+
redisRunner.discard();
108+
// updateData.title &&
109+
// (await this.redisService.setField(key, 'title', updateData.title));
110+
// updateData.content &&
111+
// (await this.redisService.setField(key, 'content', JSON.parse(content)));
112+
// updateData.emoji &&
113+
// (await this.redisService.setField(key, 'emoji', updateData.emoji));
98114

99115
// Promise.all에서 실패를 인식하기 위해 에러를 던진다.
100116
throw err;
@@ -105,9 +121,10 @@ export class TasksService {
105121
}
106122

107123
async migrateNode(key: string) {
108-
const redisData = (await this.redisService.get(
109-
key,
110-
)) as unknown as RedisNode;
124+
const data = await this.redisClient.hgetall(key);
125+
const redisData = Object.fromEntries(
126+
Object.entries(data).map(([field, value]) => [field, value]),
127+
) as RedisNode;
111128
// 데이터 없으면 오류
112129
if (!redisData) {
113130
throw new Error(`redis에 ${key}에 해당하는 데이터가 없습니다.`);
@@ -126,6 +143,7 @@ export class TasksService {
126143

127144
// 트랜잭션 시작
128145
const queryRunner = this.dataSource.createQueryRunner();
146+
const redisRunner = this.redisClient.multi();
129147
try {
130148
await queryRunner.startTransaction();
131149

@@ -136,20 +154,16 @@ export class TasksService {
136154
await nodeRepository.update(nodeId, updateData);
137155

138156
// redis에서 데이터 삭제
139-
await this.redisService.delete(key);
157+
redisRunner.del(key);
140158

141159
// 트랜잭션 커밋
142160
await queryRunner.commitTransaction();
161+
await redisRunner.exec();
143162
} catch (err) {
144163
// 실패하면 postgres는 roll back하고 redis의 값을 살린다.
145164
this.logger.error(err.stack);
146165
await queryRunner.rollbackTransaction();
147-
updateData.x &&
148-
(await this.redisService.setField(key, 'x', updateData.x.toString()));
149-
updateData.y &&
150-
(await this.redisService.setField(key, 'y', updateData.y.toString()));
151-
updateData.color &&
152-
(await this.redisService.setField(key, 'color', updateData.color));
166+
redisRunner.discard();
153167

154168
// Promise.all에서 실패를 인식하기 위해 에러를 던진다.
155169
throw err;
@@ -160,16 +174,20 @@ export class TasksService {
160174
}
161175

162176
async migrateEdge(key: string) {
163-
const redisData = (await this.redisService.get(
164-
key,
165-
)) as unknown as RedisEdge;
177+
const data = await this.redisClient.hgetall(key);
178+
const redisData = Object.fromEntries(
179+
Object.entries(data).map(([field, value]) => [field, value]),
180+
) as RedisEdge;
181+
166182
// 데이터 없으면 오류
167183
if (!redisData) {
168184
throw new Error(`redis에 ${key}에 해당하는 데이터가 없습니다.`);
169185
}
170186

171187
// 트랜잭션 시작
172188
const queryRunner = this.dataSource.createQueryRunner();
189+
const redisRunner = this.redisClient.multi();
190+
173191
try {
174192
await queryRunner.startTransaction();
175193

@@ -203,25 +221,28 @@ export class TasksService {
203221
}
204222

205223
// redis에서 데이터 삭제
206-
await this.redisService.delete(key);
224+
redisRunner.del(key);
225+
// await this.redisService.delete(key);
207226

208227
// 트랜잭션 커밋
209228
await queryRunner.commitTransaction();
210229
} catch (err) {
211230
// 실패하면 postgres는 roll back하고 redis의 값을 살린다.
212231
this.logger.error(err.stack);
213232
await queryRunner.rollbackTransaction();
214-
await this.redisService.setField(
215-
key,
216-
'fromNode',
217-
redisData.fromNode.toString(),
218-
);
219-
await this.redisService.setField(
220-
key,
221-
'toNode',
222-
redisData.toNode.toString(),
223-
);
224-
await this.redisService.setField(key, 'type', redisData.type);
233+
redisRunner.discard();
234+
235+
// await this.redisService.setField(
236+
// key,
237+
// 'fromNode',
238+
// redisData.fromNode.toString(),
239+
// );
240+
// await this.redisService.setField(
241+
// key,
242+
// 'toNode',
243+
// redisData.toNode.toString(),
244+
// );
245+
// await this.redisService.setField(key, 'type', redisData.type);
225246

226247
// Promise.all에서 실패를 인식하기 위해 에러를 던진다.
227248
throw err;

apps/websocket/src/redis/redis.service.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ export class RedisService {
1717
@Inject(RED_LOCK_TOKEN) private readonly redisLock: Redlock,
1818
) {}
1919

20-
async getAllKeys(pattern) {
21-
return await this.redisClient.keys(pattern);
22-
}
20+
// async getAllKeys(pattern) {
21+
// return await this.redisClient.keys(pattern);
22+
// }
2323

2424
createStream() {
2525
return this.redisClient.scanStream();

0 commit comments

Comments
 (0)