讀寫連線池
最後更新
本頁說明 MySQLPool 的兩個連線池分別在何時被使用,以及某一側未設定時會發生什麼事。
兩個連線池
init() 最多建立兩個 mysql2/promise 連線池(src/MySQLPool.ts:74-91):
| 連線池 | 建立條件 | 典型用途 |
|---|---|---|
讀取池 readPool |
讀取端設定的 database 非空 |
指向唯讀副本(replica) |
寫入池 writePool |
寫入端設定的 database 非空 |
指向主庫(primary) |
兩個連線池都以 waitForConnections: true 建立:連線用完時請求會排隊等待,而不是立即失敗。
每個方法走哪個連線池
| 方法 | 連線池 |
|---|---|
get() |
table() 第二個參數,預設 "read" |
insert()、update()、upsert() |
固定寫入池 |
read() |
固定讀取池 |
write() |
固定寫入池 |
query(sql, params, target) |
target;省略時沿用最近一次 table() 設定的目標 |
import MySQLPool from "@pardnchiu/mysql-pool";
// 從副本讀
const list = await MySQLPool.table("orders").where("user_id", 1).get();
// 剛寫入就要讀到最新資料時,改從主庫讀,避開複寫延遲
const fresh = await MySQLPool.table("orders", "write").where("user_id", 1).get();
table(name, "write") 只影響 get() 與之後未指定 target 的 query();寫入方法本來就走寫入池。
只設定一側
| 設定狀況 | 結果 |
|---|---|
| 只設讀取端 | 寫入端設定會沿用 config.read(傳設定物件時);以環境變數初始化時寫入池不建立,寫入方法拋出 write connection is not available. |
| 只設寫入端 | 讀取池不建立;table("x").get() 拋出 read connection is not available.,必須改寫成 table("x", "write").get() |
| 兩側皆未設定 | 兩個連線池都不建立,init() 仍會成功回傳 |
read() 與 write() 在呼叫前另外檢查連線池,錯誤訊息為 Read pool connection is not available./Write pool connection is not available.(src/MySQLPool.ts:395-404)。
單一資料庫
不需要讀寫分離時,用 config 鍵讓兩個連線池共用同一組設定:
await MySQLPool.init({
config: { host: "127.0.0.1", user: "app", password: "secret", database: "app" },
});
此時仍會建立兩個獨立的連線池,各自套用 connectionLimit,連到同一個資料庫的總連線數上限為兩者相加。