Why does async/await version of my transactional mssql app fail but callbacks version works?

风格不统一 提交于 2019-12-07 23:58:18

问题


To illuminate the problem I'm having getting a nodejs/mssql application working, I've attempted to code two functionally equivalent versions of a simple (prepared) INSERT statement wrapped in a transaction.

The callbacks version works - inserts a row into my Sql Server db.

The async / await version throws an error -

TransactionError: Can't commit transaction. There is a request in progress.

I have tried many variations of the failing version (statement reordering where plausible), but the version included below is the version that most closely mimics the logic of the working, callbacks version.

Thank you!

var sql = require('mssql');  // mssql: 4.1.0; tedious: 2.2.4; node: v8.4.0

var cfg = {
    "db": "sqlserver",
    "domain": "XXXXXX",
    "user": "cseelig",
    "password": "xxxxxx",
    "server": "xxxxxx.xxxxxx.xxxxxx.xxxxxx",
    "port": 1433,
    "stream": false,
    "options": { 
        "trustedConnection": true
    },
    "requestTimeout": 900000,
    "connectionTimeout": 30000,
    "pool": {
        "max": 3,
        "min": 0,
        "idleTimeoutMillis": 30000
    }
};

var statement = "insert into wng_dw.dbo.D_LIB_Google_Search_Query (query, LastUpdateDate) values (@query, GetDate())";

// I only run one or the other -

main1("12347");   // fails
main2("98765:);   // works

async function main1(val) {

    try {
        const conn = await new sql.connect(cfg);
        const transaction = new sql.Transaction();
        await transaction.begin();
        const ps = new sql.PreparedStatement(transaction);
        ps.input('query', sql.VarChar(200));
        await ps.prepare(statement);
        await ps.execute( {"query": val} );
        await ps.unprepare();
        await transaction.commit();
        sql.close;
    } catch(err){
        console.log("Error: " + err);
    };

    process.exit(0);

}


async function main2(val) {

    sql.connect(cfg, err => {
        const transaction = new sql.Transaction();
        transaction.begin(err => {
            const ps = new sql.PreparedStatement(transaction);
            ps.input('query', sql.VarChar(200));
            ps.prepare(statement, err => {
                ps.execute( {"query": val}, (err, result) => {
                    ps.unprepare(err => { 
                        transaction.commit(err => {
                            sql.close();
                        });
                    });
                });
            });
        });
    });

}

回答1:


The transaction.begin does not return a Promise. You could simply promisfy it. Something like the following:

await new Promise(resolve => transaction.begin(resolve));
const request = new sql.Request(transaction);
//...
await transaction.commit();

After the commit and rollback, the "request" object could not be used anymore. Otherwise it will show the error regarding the transaction didn't begin ....

Hope this help.



来源:https://stackoverflow.com/questions/48773891/why-does-async-await-version-of-my-transactional-mssql-app-fail-but-callbacks-ve

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!