forked from wangziqi/gongxue-base
修复 SQLite 钱包调账锁异常
This commit is contained in:
@@ -117,3 +117,54 @@ describe('WalletsService financial boundaries', () => {
|
|||||||
expect(dataSource.transaction).not.toHaveBeenCalled();
|
expect(dataSource.transaction).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('WalletsService wallet locking', () => {
|
||||||
|
const createQueryManager = () => {
|
||||||
|
const wallet = { id: 1, studentId: 10, balance: 0 };
|
||||||
|
const query = {
|
||||||
|
where: jest.fn(),
|
||||||
|
setLock: jest.fn(),
|
||||||
|
getOne: jest.fn(async () => wallet),
|
||||||
|
};
|
||||||
|
query.where.mockReturnValue(query);
|
||||||
|
query.setLock.mockReturnValue(query);
|
||||||
|
return {
|
||||||
|
wallet,
|
||||||
|
query,
|
||||||
|
manager: {
|
||||||
|
createQueryBuilder: jest.fn(() => query),
|
||||||
|
findOne: jest.fn(),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
it('skips pessimistic locking for SQLite', async () => {
|
||||||
|
const ctx = createQueryManager();
|
||||||
|
const service = new WalletsService(
|
||||||
|
{} as any,
|
||||||
|
{} as any,
|
||||||
|
{} as any,
|
||||||
|
{ options: { type: 'better-sqlite3' } } as any,
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = await (service as any).getOrCreateWallet(ctx.manager, 10, true);
|
||||||
|
|
||||||
|
expect(result).toBe(ctx.wallet);
|
||||||
|
expect(ctx.query.setLock).not.toHaveBeenCalled();
|
||||||
|
expect(ctx.query.getOne).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('keeps pessimistic write locking for MySQL', async () => {
|
||||||
|
const ctx = createQueryManager();
|
||||||
|
const service = new WalletsService(
|
||||||
|
{} as any,
|
||||||
|
{} as any,
|
||||||
|
{} as any,
|
||||||
|
{ options: { type: 'mysql' } } as any,
|
||||||
|
);
|
||||||
|
|
||||||
|
await (service as any).getOrCreateWallet(ctx.manager, 10, true);
|
||||||
|
|
||||||
|
expect(ctx.query.setLock).toHaveBeenCalledWith('pessimistic_write');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -259,10 +259,13 @@ export class WalletsService {
|
|||||||
if (!lock || !manager.createQueryBuilder) {
|
if (!lock || !manager.createQueryBuilder) {
|
||||||
return manager.findOne(StudentWallet, { where: { studentId } });
|
return manager.findOne(StudentWallet, { where: { studentId } });
|
||||||
}
|
}
|
||||||
return manager.createQueryBuilder(StudentWallet, 'wallet')
|
let query = manager
|
||||||
.where('wallet.studentId = :studentId', { studentId })
|
.createQueryBuilder(StudentWallet, 'wallet')
|
||||||
.setLock('pessimistic_write')
|
.where('wallet.studentId = :studentId', { studentId });
|
||||||
.getOne();
|
if (['mysql', 'mariadb', 'postgres', 'cockroachdb'].includes(this.dataSource.options.type)) {
|
||||||
|
query = query.setLock('pessimistic_write');
|
||||||
|
}
|
||||||
|
return query.getOne();
|
||||||
};
|
};
|
||||||
let wallet = await find();
|
let wallet = await find();
|
||||||
if (!wallet) {
|
if (!wallet) {
|
||||||
|
|||||||
Reference in New Issue
Block a user