mysql连接池、并发事务和@user变量



我正试图弄清楚如何在应用程序中使用mySql数据库是否有问题。我正在运行nodejs、express、mysql2,并使用连接池和多语句查询。我有多个服务器,运行不同的服务,访问同一个数据库。

在每个mySql指令集的开头,我设置了一些用户变量来检查用户凭据、最新状态等。在下面的指令中,我使用这些变量来有条件地访问一些数据,或者插入、修改数据。这里涉及到不同的参与者(nodejs、mysql2驱动程序、mysql规范、innoDb引擎(,我不确定哪一个对以下问题有明确的答案:

  • 我的多语句查询中的所有指令都将一次性运行,还是我需要担心来自不同查询和/或服务器的不同指令交织
  • 每个连接都维护用户变量。如果指令可以交错,那么不同的事务可能会打乱彼此的用户变量。将查询包装在START TRANSACTION; .... COMMIT;中可以解决问题吗

现在,我的查询的高级视图是:

const mysql2 = require('mysql2');
const pool = mysql2.createPool({
multipleStatements: 'true',
// other options...
}).promise();
[rows, fields] = await pool.query(`
// Clear variables, in case no result in found in following SELECT:
SET @enable=NULL, @status=NULL, ...;
// Check credentials, status, others:
SELECT blah_blah INTO @enable FROM ...
SELECT more_blah INTO @status FROM ...
//Do stuff based on these variables
SELECT some_stuff FROM somewhere WHERE @enable IS NOT NULL;
INSERT INTO someplace ... // conditioned on @status and others
`);

谢谢!

更好的做法是获取一个连接,并在运行多个语句时保持该连接。这里有一个完整的答案示例:node.js mysql池beginTransaction&连接

该示例显示了对具有多个查询的事务使用连接,但也应该对不属于同一事务的多个语句使用该连接。或者换句话说,在将同一连接释放回池之前,可以在同一连接上运行多个事务。

当一个线程持有一个连接并将其用于连续的查询和/或事务时,池将不会与其他线程共享它。我不是node.js的开发人员,所以我不了解node.js实现的第一手信息,但这是连接池的唯一合理实现。

此外,用户变量和其他会话状态不会泄露给其他线程。当连接返回到池时,所有会话状态都将被擦除。为了安全起见,这也是连接池实现中默认的最佳做法。你不希望你的银行路由号码存储在用户变量或临时表中,然后发现下一个用户可以读取它,因为他们碰巧从池中获得了相同的连接。

第页。S.:我从来没有发现任何需要multipleStatements选项的情况,MySQL的前工程总监告诉我:";多查询作为一种功能存在是没有正当理由的">

最新更新