Javascript 节点Firebird无效事务句柄
我在尝试按顺序提交同一事务时出错。 我正在使用节点firebird库。 第一次提交,但第二次收到以下消息: 错误:Javascript 节点Firebird无效事务句柄,javascript,node.js,firebird,node-firebird,Javascript,Node.js,Firebird,Node Firebird,我在尝试按顺序提交同一事务时出错。 我正在使用节点firebird库。 第一次提交,但第二次收到以下消息: 错误: >处的事务句柄无效(需要显式事务启动) >doCallback >(C:\Ultra\PreVendaServerV2\node\u modules\node firebird\lib\index.js:1297:21) >在 >C:\Ultra\PreVendaServerV2\node\u modules\node firebird\lib\index.js:3019:25 >
>处的事务句柄无效(需要显式事务启动)
>doCallback
>(C:\Ultra\PreVendaServerV2\node\u modules\node firebird\lib\index.js:1297:21)
>在
>C:\Ultra\PreVendaServerV2\node\u modules\node firebird\lib\index.js:3019:25
>在
>C:\Ultra\PreVendaServerV2\node\u modules\node firebird\lib\messages.js:151:25
>搜索时
>(C:\Ultra\PreVendaServerV2\node\u modules\node firebird\lib\messages.js:117:13)
>在
>C:\Ultra\PreVendaServerV2\node\u modules\node firebird\lib\messages.js:54:21
>在FSReqCallback.wrapper[as oncomplete](fs.js:520:5)处
>FSReqCallback.callbackTrampoline(内部/异步\u hooks.js:126:14){
>gdscode:335544332,GDSPARAM:未定义
当我收到相同事务的错误消息时,我正在尝试插入子项
public static async getTransaction(db: Database, ISOLATION_LEVEL?: number[]): Promise<Firebird.Transaction> {
if (!db) throw "There is no Connection with the database!";
const ISOLATION = ISOLATION_LEVEL ? ISOLATION_LEVEL : Firebird.ISOLATION_READ_COMMITED;
return new Promise(
(resolve, reject) => {
db.transaction(ISOLATION, function (err, transaction) {
if (err && LOG_SQL) { console.log(err) };
if (err) reject(err);
resolve(transaction);
});
});
}
public static async asyncInsert(insertSQL: string, params?: any[], insertChildrenCallback?: any, originObject?: any, transaction?: Firebird.Transaction, commit?: boolean) {
try {
const db = await FirebirdPromise.attach();
if (!transaction) transaction = await this.getTransaction(db);
const insertedId = await this.execQueryWithTransaction(insertSQL, transaction, params, originObject);
if (insertChildrenCallback) await insertChildrenCallback(insertedId, originObject, transaction, db);
if (commit) await this.tryCommit(transaction, db);
return new DatabaseResult({
status: DatabaseResult.RESULT_OK, message: null, data: insertedId
});
} catch (error) {
return new DatabaseResult({
status: DatabaseResult.RESULT_ERROR, message: error, data: null
});
}
}
public static async tryCommit(transaction: Firebird.Transaction, db: Database): Promise<Boolean> {
return new Promise(
(resolve, reject) => {
transaction.commit(function (err) {
if (err) {
if (LOG_SQL) console.log(err);
transaction.rollback();
reject(err);
throw err;
}
db.detach();
resolve(true);
});
});
}
公共静态异步getTransaction(db:数据库,隔离级别?:number[]):承诺{
如果(!db)抛出“与数据库没有连接!”;
const隔离=隔离级别?隔离级别:Firebird.ISOLATION\u READ\u committed;
回报新的承诺(
(解决、拒绝)=>{
事务(隔离、功能(错误、事务){
if(err&&LOG_SQL){console.LOG(err)};
如果(错误)拒绝(错误);
解决(交易);
});
});
}
公共静态异步异步插入(insertSQL:string,params?:any[],insertChildrenCallback?:any,originObject?:any,transaction?:Firebird.transaction,commit?:boolean){
试一试{
const db=wait FirebirdPromise.attach();
如果(!transaction)transaction=wait this.getTransaction(db);
const insertedId=wait this.execQueryWithTransaction(insertSQL,transaction,params,originObject);
if(insertChildrenCallback)等待insertChildrenCallback(insertedId,originObject,transaction,db);
如果(提交)等待此.tryCommit(事务,db);
返回新的数据库结果({
状态:DatabaseResult.RESULT\u正常,消息:null,数据:insertedId
});
}捕获(错误){
返回新的数据库结果({
状态:DatabaseResult.RESULT\u错误,消息:错误,数据:null
});
}
}
公共静态异步tryCommit(事务:Firebird.transaction,db:Database):承诺{
回报新的承诺(
(解决、拒绝)=>{
transaction.commit(函数(err){
如果(错误){
if(LOG_SQL)console.LOG(err);
transaction.rollback();
拒绝(错误);
犯错误;
}
db.detach();
决心(正确);
});
});
}
您似乎试图在多个函数调用中重用事务。请尝试执行以下操作:
const db=wait FirebirdPromise.attach();
事务=等待此.getTransaction(db);
您不应该从参数获取事务并多次提交,而应该每次生成事务,然后提交。对于下一次插入,请生成另一个事务。显示创建事务的代码。特别是
事务变量初始化的位置。@tbking Updated使用该信息。“尝试使用同一事务按顺序提交”-我不知道firebase的具体情况,但我怀疑这在任何数据库中都是可能的。请提供一个。我猜您正在尝试在事务句柄已提交后重用它,但鉴于您没有显示对这些插入方法等的实际调用,这只是一个猜测。如果您提交事务,您需要获得新的事务句柄。@Bergi Firebird(不是无关的Google Firebase)中有提交保留
和回滚保留
操作,但它们肯定是不常使用的特例。例如,我个人从未使用过它们。毫无疑问,正常的期望是结束事务就是结束事务。或者,OP应该生成一个事务,并为每个插入传递它,并且只有在所有插入完成后才提交。同意上面的代码更改是基于共享的代码。我很确定在足够的上下文中有更好的方法来完成。不过我会把它留给OP来找到最好的方法。
public static async getTransaction(db: Database, ISOLATION_LEVEL?: number[]): Promise<Firebird.Transaction> {
if (!db) throw "There is no Connection with the database!";
const ISOLATION = ISOLATION_LEVEL ? ISOLATION_LEVEL : Firebird.ISOLATION_READ_COMMITED;
return new Promise(
(resolve, reject) => {
db.transaction(ISOLATION, function (err, transaction) {
if (err && LOG_SQL) { console.log(err) };
if (err) reject(err);
resolve(transaction);
});
});
}
public static async asyncInsert(insertSQL: string, params?: any[], insertChildrenCallback?: any, originObject?: any, transaction?: Firebird.Transaction, commit?: boolean) {
try {
const db = await FirebirdPromise.attach();
if (!transaction) transaction = await this.getTransaction(db);
const insertedId = await this.execQueryWithTransaction(insertSQL, transaction, params, originObject);
if (insertChildrenCallback) await insertChildrenCallback(insertedId, originObject, transaction, db);
if (commit) await this.tryCommit(transaction, db);
return new DatabaseResult({
status: DatabaseResult.RESULT_OK, message: null, data: insertedId
});
} catch (error) {
return new DatabaseResult({
status: DatabaseResult.RESULT_ERROR, message: error, data: null
});
}
}
public static async tryCommit(transaction: Firebird.Transaction, db: Database): Promise<Boolean> {
return new Promise(
(resolve, reject) => {
transaction.commit(function (err) {
if (err) {
if (LOG_SQL) console.log(err);
transaction.rollback();
reject(err);
throw err;
}
db.detach();
resolve(true);
});
});
}