簡體   English   中英

使用 Node mssql 處理准備好的語句

[英]Transaction for prepared statements using Node mssql

我想創建一個 Express REST API,並將使用 MSSQL 作為數據庫部分。 我使用mssql模塊並使用PreparedStatement類。

有時我的查詢必須是事務性的,所以我也必須使用Transaction類。

我在這里找到了一些關於准備好的語句和事務的信息,但不知道如何使用准備好的語句執行事務查詢。

有人介意解釋如何在事務中使用帶有准備好的語句的 mssql 模塊嗎? 我的查詢功能應該提供一個功能,允許在我的查詢文件中寫入這樣的內容

  • 開始交易
  • 運行准備好的語句一
  • 運行准備好的語句二
  • 結束交易

所以要重現這個問題:首先,我創建了一個數據庫,其中包含一個名為“整數”的表和一個數字列“值”。

然后我使用以下代碼創建了一個空的 Node/Typescript 項目:

import sql, { ConnectionPool, PreparedStatement } from 'mssql';

class App {
    private connectionPool: ConnectionPool;

    constructor() {
        this.connectionPool = new sql.ConnectionPool(databaseConfig);
    }

    public run = async (): Promise<void> => {
        try {
            await this.connectionPool.connect();

            const preparedStatement: PreparedStatement = new sql.PreparedStatement(this.connectionPool);

            preparedStatement.input('number', sql.Numeric(18, 0));

            await preparedStatement.prepare('INSERT INTO integer (value) VALUES (@number)');
            await preparedStatement.execute({ number: 1 });
            await preparedStatement.unprepare();

            console.log('done...');
        } catch (error) {
            throw error;
        }
    }
}

(async () => {
    const app: App = new App();
    await app.run();
})().catch(error => {
    throw error;
});

到現在為止還挺好。 現在我想在一個事務中運行兩個 INSERT,但第二個傳入一個字符串,所以我預計會出現錯誤並且第一個被回滾。 我更新的run功能:

public run = async (): Promise<void> => {
    try {
        await this.connectionPool.connect();

        const transaction: Transaction = new sql.Transaction(this.connectionPool);

        const workingStatement: PreparedStatement = new sql.PreparedStatement(transaction);
        workingStatement.input('number', sql.Numeric(18, 0));

        const invalidStatement: PreparedStatement = new sql.PreparedStatement(transaction);
        invalidStatement.input('number', sql.Numeric(18, 0));

        try {
            await transaction.begin();

            await workingStatement.prepare('INSERT INTO integer (value) VALUES (@number)');
            await workingStatement.execute({ number: 1 });
            await workingStatement.unprepare();

            await invalidStatement.prepare('INSERT INTO integer (value) VALUES (@number)');
            await invalidStatement.execute({ number: false });
            await invalidStatement.unprepare();

            await transaction.commit();
        } catch (error) {
            await transaction.rollback();
            console.log('execution failed...');
        }

        console.log('done...');
    } catch (error) {
        throw error;
    }
}

現在我收到這個錯誤

(節點:18416)未處理的PromiseRejectionWarning:TransactionError:無法回滾事務。 有一個請求正在進行中。

而且我不確定我的語法是否錯誤。

我相信您遇到的錯誤是因為您沒有按照文檔中的建議調用unprepare

請記住,在調用 unprepare 之前,您無法執行事務中的其他請求

在回滾事務之前對語句調用unprepare對我有用:

try {
  // ...
  await invalidStatement.prepare('INSERT INTO integer (value) VALUES (@number)');
  try {
    await invalidStatement.execute({ number: false });
  } finally {
    await invalidStatement.unprepare();
  }
} catch (error) {
  // rollback here...
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM