鎖與分區是 Oracle 併發控制與大數據管理的兩大核心支柱。本文詳細剖析行級鎖、表級鎖(共享/獨占/行共享)、WAIT/NOWAIT/SKIP LOCKED 子句,以及四大分區類型(範圍、雜湊、複合、清單)與分區維護操作,提供實戰可用的完整語法範例。
Oracle 預設以行級鎖實現最高併發度,僅鎖定被修改的資料列,讀取不阻塞寫入,寫入不阻塞讀取(多版本一致性讀取)。
-- 建立測試用戶與權限
CONNECT system/manager;
CREATE USER user2 IDENTIFIED BY chenmp;
GRANT CREATE SESSION TO user2;
GRANT SELECT, INSERT, UPDATE, DELETE ON testlock TO user2;
-- Session 1 (user2) 更新 id=8,未提交
CONNECT user2/chenmp;
UPDATE yyaccp.testlock SET name = 'wrong' WHERE id = 8;
-- Session 2 (yyaccp) 嘗試更新同一列 → 等待
CONNECT yyaccp/accp;
UPDATE testlock SET name = 'jeff wrong' WHERE id = 8; -- 阻塞等待
-- Session 1 COMMIT 或 ROLLBACK 後,Session 2 才繼續
FOR UPDATE NOWAIT:立即失敗 (ORA-00054) 若資源被鎖。FOR UPDATE WAIT n:最多等待 n 秒再失敗(僅限 SELECT)。FOR UPDATE SKIP LOCKED (11g+):跳過已鎖定列,適合工作佇列模式。-- Session 1
CONNECT user2/chenmp;
SELECT * FROM yyaccp.testlock WHERE id = 8 FOR UPDATE;
-- Session 2 (另一視窗)
CONNECT yyaccp/accp;
SELECT * FROM testlock WHERE id = 8 FOR UPDATE WAIT 5; -- 等待 5 秒
-- 或
SELECT * FROM testlock WHERE id = 8 FOR UPDATE NOWAIT; -- 立即報錯
手動鎖定整張表,模式決定相容性:
| 模式 | 語法 | 允許他人操作 | 阻塞他人操作 |
|---|---|---|---|
| ROW SHARE (RS) | LOCK TABLE t IN ROW SHARE MODE | 查詢、INSERT、UPDATE、DELETE、ROW SHARE、ROW EXCLUSIVE | SHARE、SHARE ROW EXCLUSIVE、EXCLUSIVE |
| ROW EXCLUSIVE (RX) | LOCK TABLE t IN ROW EXCLUSIVE MODE | 查詢、INSERT、UPDATE、DELETE、ROW SHARE、ROW EXCLUSIVE | SHARE、SHARE ROW EXCLUSIVE、EXCLUSIVE |
| SHARE (S) | LOCK TABLE t IN SHARE MODE | 查詢、SHARE | INSERT/UPDATE/DELETE、ROW EXCLUSIVE、SHARE ROW EXCLUSIVE、EXCLUSIVE |
| SHARE ROW EXCLUSIVE (SRX) | LOCK TABLE t IN SHARE ROW EXCLUSIVE MODE | 查詢 | 所有 DML、SHARED、SRX、EXCLUSIVE |
| EXCLUSIVE (X) | LOCK TABLE t IN EXCLUSIVE MODE | 查詢 | 所有 DML 及任何鎖模式 |
-- Session 1
CONNECT user2/chenmp;
LOCK TABLE yyaccp.testlock IN SHARE MODE;
-- Session 2
CONNECT yyaccp/accp;
DELETE FROM testlock; -- 阻塞,直到 Session 1 COMMIT/ROLLBACK
CONNECT yyaccp/accp; LOCK TABLE testlock IN SHARE MODE;
CONNECT user2/chenmp; LOCK TABLE testlock IN SHARE MODE;
CONNECT user1/user1; UPDATE testlock SET name='ping' WHERE id=8; -- 阻塞
-- 需 yyaccp 與 user2 皆 COMMIT/ROLLBACK 釋放鎖後,user1 才能繼續
-- Session 1
CONNECT user2/chenmp;
LOCK TABLE yyaccp.testlock IN ROW SHARE MODE;
UPDATE yyaccp.testlock SET name='ping' WHERE id=8; -- 成功
-- Session 2
CONNECT yyaccp/accp;
UPDATE yyaccp.testlock SET name='ping' WHERE id=8; -- 阻塞(同列)
UPDATE yyaccp.testlock SET name='wrong' WHERE id=7; -- 成功(不同列)
LOCK TABLE yyaccp.testlock IN EXCLUSIVE MODE NOWAIT;
分區將大表切分為較小、可獨立管理的片段,提升查詢效能(分區裁剪)、維護彈性(分區級匯入/匯出/截斷/移動)與可用性。
依欄位值範圍對應分區,常用於日期、序號。
DROP TABLE employeeinfo;
CREATE TABLE employeeinfo (
empid NUMBER(5),
emp_name VARCHAR2(20) NOT NULL,
age NUMBER(10)
)
PARTITION BY RANGE (age) (
PARTITION p1 VALUES LESS THAN (20),
PARTITION p2 VALUES LESS THAN (30),
PARTITION p3 VALUES LESS THAN (40)
);
DROP TABLE personinfo CASCADE CONSTRAINTS;
CREATE TABLE personinfo (
person_id NUMBER(5),
person_name VARCHAR2(20),
birthday DATE NOT NULL
)
PARTITION BY RANGE (birthday) (
PARTITION p1 VALUES LESS THAN (TO_DATE('1978-10-10','YYYY-MM-DD')),
PARTITION p2 VALUES LESS THAN (TO_DATE('1980-05-01','YYYY-MM-DD')),
PARTITION p3 VALUES LESS THAN (MAXVALUE)
);
對分區鍵雜湊運算均勻分布,適合無明顯範圍特徵的鍵值,減少 I/O 熱點。
DROP TABLE my_emp CASCADE CONSTRAINTS;
CREATE TABLE my_emp (
empno NUMBER(4),
ename VARCHAR2(15)
)
PARTITION BY HASH (empno) (
PARTITION part_1,
PARTITION part_2
);
先範圍分區,再於各分區內雜湊子分區,兼具管理便利與並行效能。
DROP TABLE employees CASCADE CONSTRAINTS;
CREATE TABLE employees (
emp_id VARCHAR2(5),
work_date DATE NOT NULL,
salary NUMBER(10)
)
PARTITION BY RANGE (salary)
SUBPARTITION BY HASH (emp_id)
SUBPARTITIONS 5 (
PARTITION p1 VALUES LESS THAN (1500),
PARTITION p2 VALUES LESS THAN (2000),
PARTITION p3 VALUES LESS THAN (MAXVALUE)
);
明確指定離散值對應分區,適合業務分類(如產品類型)。
DROP TABLE product CASCADE CONSTRAINTS;
CREATE TABLE product (
product_id NUMBER(4),
product_type VARCHAR2(20),
product_name VARCHAR2(50)
)
PARTITION BY LIST (product_type) (
PARTITION p1 VALUES ('book'),
PARTITION p2 VALUES ('cd', 'dvd')
);
| 操作 | 語法範例 | 說明 |
|---|---|---|
| 新增分區 | ALTER TABLE my_emp ADD PARTITION part_3; | 雜湊分區需指定分區名;範圍分區需指定 VALUES LESS THAN |
| 刪除分區 | ALTER TABLE sales DROP PARTITION p4; | 資料同步刪除,不可恢復 |
| 截斷分區 | ALTER TABLE sales TRUNCATE PARTITION p3; | 保留分區結構,高速清空資料 |
| 合併分區 | ALTER TABLE employeeinfo MERGE PARTITIONS p1, p2 INTO PARTITION p2; | 僅相鄰範圍分區;結果繼承較高上界 |
| 拆分分區 | ALTER TABLE employeeinfo SPLIT PARTITION p2 AT (20) INTO (PARTITION p1, PARTITION p2); | 將大分區拆小,需指定新界點 |
| 重命名分區 | ALTER TABLE sales RENAME PARTITION p1 TO p5; | 元資料操作,極快 |
-- 表分區資訊
SELECT * FROM user_tab_partitions;
-- 索引分區資訊
SELECT * FROM user_ind_partitions;
FOR UPDATE SKIP LOCKED。深入理解鎖與分區,是打造高併發、可擴展 Oracle 系統的關鍵能力。