Knex操作MSSQL事务报非LoggedIn状态错误、连接重置问题
问题环境
- 运行时:Node 10.21.0
- 依赖版本:
knex@^0.16.3、mssql@^4.1.0
问题复现代码
事务调用逻辑:
await this.repository.transaction(async (transaction) => { try { await this.repository.deleteData(transaction); result = await this.repository.postData(data, transaction); await transaction.commit(); } catch (e) { await transaction.rollback(); throw (e); } });
Repository层对应方法:
async deleteData(transaction) { const result = await this.knex.raw(` DELETE Table1 `) .transacting(transaction); return result; } async postData(data, transaction) { const query = this.knex.batchInsert('Table1', data, 10) .returning('id') .transacting(transaction); const result = await query; return result; }
运行抛出错误:
TransactionError: Requests can only be made in the LoggedIn state, not the Final state
ConnectionError: Connection lost - write ECONNRESET, "Connection Closed before request completed"
问题诱因
核心原因是Knex事务生命周期管理逻辑冲突:
- 当向
knex.transaction()传入异步回调函数时,Knex默认开启自动事务管理:回调内所有异步操作正常resolve则自动提交事务,回调抛出异常则自动回滚事务,不需要手动调用commit()/rollback()。 - 代码中在回调内手动执行
commit()后,事务绑定的数据库连接已经进入Final结束状态、被归还到连接池。此时Knex在回调执行完成后,还会尝试执行自动收尾的事务状态操作,向已经关闭的连接发送请求,就会触发状态不合法的报错,后续连接被强制重置就会抛出ECONNRESET、请求完成前连接关闭的异常。 - 当前使用的
mssql@4.1.0驱动对连接状态校验严格,重复提交/回滚事务的操作不会被静默忽略,会直接抛出异常打断执行。
修复方案
优先使用Knex自带的自动事务管理,删除回调内手动的commit、rollback和冗余try/catch逻辑,修改后的事务代码如下:
result = await this.repository.transaction(async (transaction) => { await this.repository.deleteData(transaction); return this.repository.postData(data, transaction); });
逻辑说明:
- 只要deleteData或postData任意一步抛出错误,Knex会自动执行回滚,异常会正常向外抛出,不需要手动处理。
- 所有操作执行成功后Knex会自动提交事务,回调的返回值会作为
transaction()方法的执行结果赋值给result。
如果确实需要手动控制事务提交/回滚节点,就不要给transaction()传入回调,手动获取事务对象处理,写法如下:
const transaction = await this.repository.transaction(); try { await this.repository.deleteData(transaction); result = await this.repository.postData(data, transaction); await transaction.commit(); } catch (e) { await transaction.rollback(); throw e; }
额外注意:当前deleteData方法内的DELETE Table1语句没有WHERE条件,会清空整张表的数据,如果不是业务预期的全表删除操作,请补充对应过滤条件,避免数据误删。
内容的提问来源于stack exchange,提问作者Developer
相关产品推荐
相关产品推荐

