您好,我正在使用类似于外观设计模式的设计编写简单的Web应用程序。应用程序使用Typescript使用nodejs,expressjs,node-postres和inverseify编写。假设我有一个简单的例子
Router.ts
router.get('/test', testController.test);
TestController.ts
import { Request, Response } from 'express';
import { ITestUC } from '../usecase/TestUC';
import { di } from '../core/Di';
import { TYPES } from '../core/Types';
class TestController {
public async test(req: Request, res: Response, next: Function) {
const uc = di.get<ITestUC>(TYPES.ITestUC);
await uc.run();
res.send({ data:1 });
}
}
export const testController = new TestController();
TestUC.ts
import "reflect-metadata";
import { injectable, interfaces } from "inversify";
import { di } from "../core/Di";
import { TYPES } from "../core/Types";
import { ITestManager1 } from "../library/Test/TestManager1";
import { ITestManager2 } from "../library/Test/TestManager2";
import { PoolClient } from "pg";
import { PostgresClient, IPostgresClient } from "../core/PostgresClient";
import { IPostgresPool } from "../core/PostgresPool";
function db(transaction: boolean) {
return (target: any, property: string, descriptor: TypedPropertyDescriptor<() => void>) => {
const fn = descriptor.value;
if(!fn) return;
descriptor.value = async function (){
let poolClient: PoolClient,
postgresClient: PostgresClient = new PostgresClient();
try {
poolClient = await di.get<IPostgresPool>(TYPES.IPostgresPool).pool.connect();
postgresClient.set(poolClient);
di.rebind<IPostgresClient>(TYPES.IPostgresClient).toDynamicValue((context: interfaces.Context) => { return postgresClient });
if (transaction) postgresClient.begin();
await fn.apply(this);
if (transaction) postgresClient.commit();
} catch (e) {
if (transaction) postgresClient.rollback();
throw e;
} finally {
postgresClient.get().release();
}
}
}
}
@injectable()
export class TestUC implements ITestUC {
@db(true)
public async run(): Promise<void> {
const manager1 = await di.get<ITestManager1>(TYPES.ITestManager1);
manager1.test1('m1');
const manager2 = await di.get<ITestManager2>(TYPES.ITestManager2);
manager2.test1('m2');
}
}
export interface ITestUC {
run(): Promise<void>
}
TestManager1.ts
import { injectable, inject} from "inversify";
import "reflect-metadata";
import { TYPES } from "../../core/Types";
import { ITestSql1 } from "./TestSql1";
@injectable()
export class TestManager1 implements ITestManager1 {
@inject(TYPES.ITestSql1) private sql: ITestSql1;
public async test1(value: string) {
await this.sql.test1(value);
}
}
export interface ITestManager1 {
test1(value: string)
}
TestSql1.ts
import { injectable, inject } from "inversify";
import "reflect-metadata";
import { IPostgresClient } from "../../core/PostgresClient";
import { TYPES } from "../../core/Types";
@injectable()
export class TestSql1 implements ITestSql1{
@inject(TYPES.IPostgresClient) db: IPostgresClient;
public async test1(value: string) {
const query = {
name: 'insert-test',
text: `
INSERT INTO pr.test (
process,
operation,
key
) VALUES (
$1,
$2,
$3
)`,
values: [
this.db.get()['processID'],
1,
value
]
};
await this.db.get().query(query);
}
}
export interface ITestSql1 {
test1(value: string)
}
PostgresClient.ts
import { PoolClient } from "pg";
export class PostgresClient implements IPostgresClient {
private client: PoolClient;
get(): PoolClient {
return this.client;
}
set(client: PoolClient) {
this.client = client;
}
async begin() {
await this.client.query('BEGIN');
}
async commit() {
await this.client.query('COMMIT');
}
async rollback() {
await this.client.query('ROLLBACK');
}
}
export interface IPostgresClient {
get(): PoolClient;
set(client: PoolClient);
commit();
rollback();
begin();
}
TestManager2.ts和TestSql2.ts与TestManager1.ts和TestSql1.ts基本相同
我的问题是,每个请求似乎仅使用来自池的一个相同的postgresql连接(已通过JMeter测试)并序列化了所有api请求。 Pool甚至不创建与Postgresql的其他连接。看起来其他请求正在等待上一个请求结束或postgresql连接发布。
如何使用node-postgres池为每个请求实例化一个连接(事务),同时又不阻止其他请求?
此代码是否被阻止?还是我误解了文档中的内容?还是仅仅是这种设计不适用于nodejs?我真的现在不在,呆了一周。