简体   繁体   中英

node mssql transaction sequential requests

I am using mssql package within an azure function...trying to perform sequential writes to a database within a single transaction. The aim is that the transactions are to roll back if there is an error in either one. This looks to be working with the below code but I can't figure out how to send back whether the transaction is successful/rolled back (and ultimately communicate this to the client). I have looked at the transaction documentation for mssql but they only have examples for a SINGLE request. Not multiple requests. What is the best way to do this?

In the below code, Request2 is the request that is supposed to fail due to a misspelling of the table name. As I said, it seems that the rolling back is occurring because NEITHER writes are occurring. Also, the 'error committing transaction' is getting logged in the console... but I can't get this error out into the azure function to then respond to the client correctly. I just want to be able to pick up an error in the trasaction.commit() stage and then send this back, but it seems the context.res is being run straight away. How do I fix this? I obviously don't understand the async properties properly. Does anyone have a good example of how to run sequential queries in a transaction with node mssql? I can't find any good examples online.

const runQuery = async () => {
var errors = [];


let pool = await sql.connect(sqlConfig);

const transaction = new sql.Transaction(pool);

transaction.begin(async (err) => {
  let rolledBack = false;

  transaction.on("rollback", (aborted) => {
    console.log("rolledback");
    rolledBack = true;
  });
  const request = new sql.Request(transaction);
  request.query(
    "insert into categories (category) values ('Test ')",
    async (err, result) => {
      if (err) {
        console.log("error 1");
        errors.push(err);
        // return "error in req1";
        if (!rolledBack) {
          console.log("rollback 1 below");
          await transaction.rollback((err) => {
            console.log("rolling back 1");
          });
        }
      }

      const request2 = new sql.Request(transaction);

      request2.query(
        "insert into adjustment values ('AAA', 0)",
        async (err, result) => {
          if (err) {
            console.log("error 2");
            errors.push(err);
            if (!rolledBack) {
              console.log("rollback 2 below");
              await transaction.rollback((err) => {
                console.log("rolling back");
                // console.log(err);
              });
            }
          }

          transaction.commit((err) => {
            if (err) {
              console.log("error in committing transaction");
              return "error";
              // console.log(err);
            } else {
              return "success";
            }
          });
        }
      );
    }
  );
});

};

const queryResult = await runQuery();

context.res = { body: queryResult, }; };

After you handled the error returned by the commit(), your function should return error code and message. Then you can fill the response as below,

 context.res = { status: queryResult.responseCode, body : queryResult.mesg};

For instance, the runQuery() function could return 400 as responseCode and "Something went wrong, details of error" as mesg . You could also log your errors such that you can find log and trace messages in the Application Insights blade for your function app. So that you can easily debug what went on inside your code. See this documentation to log errors.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM