# 讀寫連線池

本頁說明 `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()` 設定的目標 |

```typescript
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` 鍵讓兩個連線池共用同一組設定：

```typescript
await MySQLPool.init({
  config: { host: "127.0.0.1", user: "app", password: "secret", database: "app" },
});
```

此時仍會建立兩個獨立的連線池，各自套用 `connectionLimit`，連到同一個資料庫的總連線數上限為兩者相加。

## 相關頁面

- [設定](/zh/configuration)：設定來源優先序與預設值
- [原生 SQL](/zh/raw-sql)：以固定連線池執行手寫 SQL
