---
title: "髒讀（Dirty Read）"
slug: dirty-read
language: zh-TW
source: https://aiterms.tw/terms/dirty-read
updated_at: 2026-06-22
tags: [資料庫, 交易管理, 並行控制, 隔離等級, 資料一致性]
ipas_term: false
---

# 髒讀（Dirty Read）

資料庫交易讀取到另一個尚未提交之交易所寫入的中間態資料，造成資料不一致的現象。

## 完整說明

髒讀（Dirty Read）是資料庫並行控制中的一種異常現象，發生在交易 A 讀取到交易 B 已修改但尚未提交（COMMIT）的資料時；若交易 B 隨後執行回滾（ROLLBACK），則交易 A 讀到的資料在資料庫中根本就不存在，導致基於該資料的後續操作出現錯誤。髒讀可透過設定交易隔離等級為「讀已提交（Read Committed）」或更高級別來避免。

## 常見問題

### 髒讀和不可重複讀有什麼區別？

兩者都是並發交易下的讀取異常，但觸發條件不同。髒讀發生在讀取到「未提交」的資料：交易 A 讀取了交易 B 尚未 COMMIT 的修改，若 B 後來 ROLLBACK，A 就讀到了從未真正存在的資料。不可重複讀（Non-Repeatable Read）則發生在讀取到「已提交」的修改：交易 A 在同一個交易中兩次讀取同一欄位，期間交易 B 提交了修改，導致兩次讀取結果不同。防止髒讀只需讀已提交（Read Committed）等級；防止不可重複讀則需可重複讀（Repeatable Read）等級。兩者的嚴重性不同，髒讀通常更危險，因為它讀到的資料可能在資料庫歷史上根本不存在。

### 在預設設定下，常見資料庫（MySQL、PostgreSQL）會有髒讀問題嗎？

不會，主流資料庫的預設隔離等級都能防止髒讀。PostgreSQL 和 Oracle 的預設隔離等級是讀已提交（Read Committed），天然防止髒讀；MySQL InnoDB 的預設隔離等級是可重複讀（Repeatable Read），同樣防止髒讀且保護更強。只有當開發者明確將隔離等級設為「讀未提交（Read Uncommitted）」時，才會允許髒讀發生。在實際開發中，除非有特殊性能需求且能接受資料不一致，否則不建議使用讀未提交等級。如果在應用層面發現資料不一致，更常見的原因是應用程式邏輯錯誤或缺少適當的交易邊界，而非資料庫隔離等級設定。

### NoSQL 資料庫（如 MongoDB、Redis）也有髒讀問題嗎？

NoSQL 資料庫對交易和隔離等級的支援程度差異很大。MongoDB 自 4.0 版起支援多文件 ACID 交易，提供類似 Read Committed 等級的隔離保護；在單文件操作上，MongoDB 原生保證原子性，不存在髒讀。Redis 支援 MULTI/EXEC 交易塊，在 EXEC 執行前命令只是排隊，無法中途讀取到部分狀態，因此不會有傳統意義的髒讀；但 Redis 的 WATCH 機制（樂觀鎖）若設計不當，可能出現其他類型的競態條件。整體而言，NoSQL 資料庫通常在一致性與可用性之間做不同取捨（CAP 定理），評估時需查閱各資料庫的具體文件，而非直接套用 SQL 的隔離等級概念。

---

來源：https://aiterms.tw/terms/dirty-read
快查頁：https://aiterms.tw/terms/dirty-read
最後更新：2026/06/22
深度解說：https://aiterms.tw/learning/what-is-dirty-read