feat(dict) 分布式锁
This commit is contained in:
parent
cd49a78678
commit
e8e352b6b6
@ -13,6 +13,7 @@ import { sysDict } from '@/eneities';
|
||||
import { eq, and, or, ne, desc, asc, sql, inArray, isNull, not, max } from 'drizzle-orm';
|
||||
import { successResponse, BusinessError } from '@/utils/responseFormate';
|
||||
import { nextId } from '@/utils/snowflake';
|
||||
import { DistributedLockService } from '@/utils/distributedLock';
|
||||
import type {
|
||||
CreateDictRequest,
|
||||
GetDictTreeByCodeRequest,
|
||||
@ -43,6 +44,11 @@ export class DictService {
|
||||
* @throws BusinessError 业务逻辑错误
|
||||
*/
|
||||
public async createDict(body: CreateDictRequest): Promise<CreateDictSuccessType> {
|
||||
const pid = body.pid || '0';
|
||||
const lockKey = `dict:create:code:${body.code}:name:${body.name}:pid:${pid}`;
|
||||
const lock = await DistributedLockService.acquire({ key: lockKey, ttl: 10 });
|
||||
|
||||
try {
|
||||
// 1. code唯一性校验
|
||||
const existCode = await db()
|
||||
.select({ id: sysDict.id })
|
||||
@ -54,7 +60,6 @@ export class DictService {
|
||||
}
|
||||
|
||||
// 2. name同级唯一性校验
|
||||
const pid = body.pid || '0';
|
||||
const existName = await db()
|
||||
.select({ id: sysDict.id })
|
||||
.from(sysDict)
|
||||
@ -143,6 +148,9 @@ export class DictService {
|
||||
},
|
||||
'创建字典项成功',
|
||||
);
|
||||
} finally {
|
||||
await lock.release();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -328,6 +336,8 @@ export class DictService {
|
||||
* @returns Promise<UpdateDictSuccessType>
|
||||
*/
|
||||
public async updateDict(id: string, body: UpdateDictBodyRequest): Promise<UpdateDictSuccessType> {
|
||||
const lock = await DistributedLockService.acquire({ key: `dict:update:${id}`, ttl: 10 });
|
||||
try {
|
||||
Logger.info(`更新字典项: ${id}, body: ${JSON.stringify(body)}`);
|
||||
|
||||
// 1. 检查字典项是否存在
|
||||
@ -400,6 +410,9 @@ export class DictService {
|
||||
},
|
||||
'更新字典项成功',
|
||||
);
|
||||
} finally {
|
||||
await lock.release();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -410,6 +423,8 @@ export class DictService {
|
||||
* @description 处理字典项的排序和移动(改变父级),使用原生SQL保证性能和类型安全
|
||||
*/
|
||||
public async sortDict(body: SortDictRequest): Promise<SortDictSuccessType> {
|
||||
const lock = await DistributedLockService.acquire({ key: `dict:sort`, ttl: 30 });
|
||||
try {
|
||||
const { items } = body;
|
||||
if (!items || items.length === 0) {
|
||||
throw new BusinessError('排序项列表不能为空', 400);
|
||||
@ -485,12 +500,14 @@ export class DictService {
|
||||
if (error instanceof BusinessError) {
|
||||
throw error;
|
||||
}
|
||||
Logger.error('字典项排序失败', { error });
|
||||
throw new BusinessError('字典项排序失败,请稍后重试', 500);
|
||||
}
|
||||
|
||||
Logger.info('字典项排序成功');
|
||||
return successResponse(null, '字典项排序成功');
|
||||
} finally {
|
||||
await lock.release();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -504,6 +521,8 @@ export class DictService {
|
||||
id,
|
||||
cascade,
|
||||
}: DeleteDictRequest): Promise<DeleteDictSuccessType> {
|
||||
const lock = await DistributedLockService.acquire({ key: `dict:delete:${id}`, ttl: 10 });
|
||||
try {
|
||||
const dictId = BigInt(id);
|
||||
Logger.info(`请求删除字典项: ${dictId}, 是否级联: ${!!cascade}`);
|
||||
|
||||
@ -566,12 +585,14 @@ export class DictService {
|
||||
if (error instanceof BusinessError) {
|
||||
throw error;
|
||||
}
|
||||
Logger.error('字典项删除失败', { error });
|
||||
throw new BusinessError('字典项删除失败,请稍后重试', 500);
|
||||
}
|
||||
|
||||
Logger.info(`字典项 ${dictId} 及关联子项(如有)已成功软删除`);
|
||||
return successResponse(null, '字典项删除成功');
|
||||
} finally {
|
||||
await lock.release();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user