[英]Transaction for prepared statements using Node mssql
I want to create an Express REST API and will use MSSQL for the database part.我想创建一个 Express REST API,并将使用 MSSQL 作为数据库部分。 I use the mssql module and use the
PreparedStatement
class.我使用mssql模块并使用
PreparedStatement
类。
Sometimes my queries have to be transactional, so I have to work with the Transaction
class too.有时我的查询必须是事务性的,所以我也必须使用
Transaction
类。
I found some information about prepared statements here and about transactions here but don't know how to execute transactional queries using prepared statements.我在这里找到了一些关于准备好的语句和事务的信息,但不知道如何使用准备好的语句执行事务查询。
Would someone mind explaining how to use the mssql module with prepared statements within transactions?有人介意解释如何在事务中使用带有准备好的语句的 mssql 模块吗? My query function should provide a functionality giving access to write something like this in my query file
我的查询功能应该提供一个功能,允许在我的查询文件中写入这样的内容
So to reproduce the problem: First I created a database with a table called "integer" and a numeric column "value".所以要重现这个问题:首先,我创建了一个数据库,其中包含一个名为“整数”的表和一个数字列“值”。
Then I created an empty Node/Typescript project with this code:然后我使用以下代码创建了一个空的 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;
});
So far so good.到现在为止还挺好。 Now I want to run two INSERTs within a transaction but the second one passes in a string so I would expect an error and the first one gets rolled back.
现在我想在一个事务中运行两个 INSERT,但第二个传入一个字符串,所以我预计会出现错误并且第一个被回滚。 My updated
run
function:我更新的
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;
}
}
Now I get this error现在我收到这个错误
(node:18416) UnhandledPromiseRejectionWarning: TransactionError: Can't rollback transaction.
(节点:18416)未处理的PromiseRejectionWarning:TransactionError:无法回滚事务。 There is a request in progress.
有一个请求正在进行中。
And I'm not sure if my syntax is wrong.而且我不确定我的语法是否错误。
I believe the error you're hitting happens because you didn't call unprepare
as suggested in the docs:我相信您遇到的错误是因为您没有按照文档中的建议调用
unprepare
:
keep in mind you can't execute other requests in the transaction until you call unprepare
请记住,在调用 unprepare 之前,您无法执行事务中的其他请求
Calling unprepare
on the statement before rolling back the transaction works for me:在回滚事务之前对语句调用
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.