cool-team-official / cool-admin-midway

🔥 cool-admin(midway版)一个很酷的后台权限管理框架,Ai编码、流程编排、模块化、插件化、CRUD极速开发,永久开源免费,基于midway.js 3.x、typescript、typeorm、mysql、jwt、vue3、vite、element-ui等构建
https://cool-js.com
MIT License
2.65k stars 588 forks source link

RpcTransaction Bug #138

Open hanxiaolong-github opened 1 year ago

hanxiaolong-github commented 1 year ago

这个RPCTransaction 有个bug :https://github.com/cool-team-official/cool-admin-midway-rpc/issues/3 麻烦能尽快update 一下吗?想要用这个cool 做点开发。

cool-team-official commented 1 year ago

已收到您的请求,预计今天排查更新

cool-team-official commented 1 year ago

这种高频的调用,建议你将连接数提高,

hanxiaolong-github commented 1 year ago

每个CoolRpcTransaction 打开一个新的数据库连接,这样很浪费数据库连接,会导致系统能同时支持的用户访问数量减少。也不是多麻烦的修改,几句code 就能解决。 下面这个修改我是经过压力测试的。 return (target, propertyKey, descriptor) => { const method = descriptor.value; descriptor.value = async function (...args) { let rpcTransactionId; let isCaller;

    // 获取传送过来的 rpcTransactionId
    // 尝试从第一个参数中获取。
    if (args[0]) {
      rpcTransactionId = args[0].rpcTransactionId;
    }
    // 尝试从第二个参数中获取
    if(args[1] && !rpcTransactionId){
      rpcTransactionId = args[1];
    }

    if(rpcTransactionId){
      isCaller = false;
    }
    else{// 如果没有事务ID,手动创建 
      isCaller = true;
      rpcTransactionId = uuid_1.v1();
    }

    let data;
    let queryRunner;
    if(global['moleculer.transactions'][rpcTransactionId]){
        queryRunner = global['moleculer.transactions'][rpcTransactionId];
    }else{
        const connection = typeorm_1.getConnection((option === null || option === void 0 ? void 0 : option.connectionName) || 'default');
        queryRunner = connection.createQueryRunner();
        // 使用我们的新queryRunner建立真正的数据库连
        console.log('start connect....')
        await queryRunner.connect();
        console.log('end connect....')
        if (option && option.isolation) {
            await queryRunner.startTransaction(option.isolation);
        }
        else {
            await queryRunner.startTransaction();
        }
    }
    try {
        global['moleculer.transactions'][rpcTransactionId] = queryRunner;
        // 半小时后清除
        setTimeout(() => {
            if(global['moleculer.transactions'][rpcTransactionId]){
                global['moleculer.transactions'][rpcTransactionId].release();
                delete global['moleculer.transactions'][rpcTransactionId];
            }
        }, 1800 * 1000);
        data = await method.apply(this, [
            ...args,
            rpcTransactionId,
            queryRunner,
        ]);
        if (isCaller) {
            global['moleculer:broker'].broadcast('moleculer.transaction', {
                rpcTransactionId,
                commit: true,
            });
        }
        //await queryRunner.commitTransaction();
    }
    catch (error) {
        //await queryRunner.rollbackTransaction();
        if (isCaller) {
            global['moleculer:broker'].broadcast('moleculer.transaction', {
                rpcTransactionId,
                commit: false,
            });
        }
        console.log(error);
        console.log(error.stack);
        throw new core_1.CoolCommException(error.message);
    }
    return data;
};
return descriptor;

};

hanxiaolong-github commented 1 year ago

还有情况,可能存在在循环中调用CoolRpcTransaction 包裹的方法,这样就是再多是数据库连接也不够浪费的。

cool-team-official commented 1 year ago

程序设计 不应该存在 循环调用事务,得尽量避免这种情况