簡體   English   中英

mysql 連接池、並發事務和@用戶變量

[英]mysql connection pool, concurrent transactions and @ user variables

我想弄清楚在應用程序中如何使用 mySql 數據庫是否有問題。 我正在運行 nodejs、express、mysql2,並使用連接池,以及多個語句查詢。 我有多個服務器,運行不同的服務,訪問同一個數據庫。

在每個 mySql 指令集的開頭,我設置了一些用戶變量來檢查用戶憑據、最新狀態等......在下面的說明中,我使用這些變量有條件地訪問一些數據,或者也做插入、修改數據。 這里涉及到不同的參與者(nodejs、mysql2 驅動程序、mysql 規格、innoDb 引擎),我不確定哪個對以下問題有明確的答案:

  • 我的多個語句查詢中的所有指令是否將一次性運行,還是我需要擔心來自不同查詢和/或服務器交錯的不同指令?
  • 每個連接都維護用戶變量。 如果指令可以交錯,我最終可能會以不同的事務混淆彼此的用戶變量。 將查詢包裝在START TRANSACTION; .... COMMIT; 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 pool beginTransaction & connection

該示例顯示了將連接用於具有多個查詢的事務,但也應該將該連接用於不屬於同一事務的多個語句。 或者換一種說法,在該連接被釋放回池之前,可以在同一個連接上運行多個事務。

雖然一個線程持有一個連接並將其用於連續查詢和/或事務,但池不會與其他線程共享它。 我不是 node.js 開發人員,所以我不了解 node.js 實現的第一手資料,但這是連接池的唯一合理實現。

此外,用戶變量和其他 session state 不會泄露給其他線程。 當連接返回到池時,所有 session state 都會被擦除。 為了安全起見,這也是連接池實現中默認的最佳實踐。 您不希望您的銀行路由號碼存儲在用戶變量或臨時表中,然后發現下一個用戶可以讀取它,因為他們有機會從池中獲取相同的連接。

PS:我從來沒有發現任何需要multipleStatements選項的案例,MySQL的前工程總監告訴我:“沒有正當理由將多查詢作為一項功能存在。”

暫無
暫無

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

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