DML鎖有行鎖(Row Locks,TX)和表鎖(Table Locks,TM),不同的DML操作會自動請求對應的鎖。
create table employees(employee_id number(10),salary number(10)); insert into employees(employee_id,salary) values(100,512); insert into employees(employee_id,salary) values(101,600); ......步驟一:三個Session同時查詢ID為100和101的雇員,查詢結果一致
Session 1: SELECT employee_id, salary FROM employees WHERE employee_id IN (100, 101); EMPLOYEE_ID SALARY ------------------------- 100 512 101 600 Session 2: SELECT employee_id, salary FROM employees WHERE employee_id IN (100, 101); EMPLOYEE_ID SALARY ------------------------- 100 512 101 600 Session 3: SELECT employee_id, salary FROM employees WHERE employee_id IN (100, 101); EMPLOYEE_ID SALARY ------------------------- 100 512 101 600步驟二:Session 1執行更新操作,更新id為100的雇員,在這個更新中,寫者將請求一個行鎖,阻止其它寫者更新這行數據,如果其它寫者更新該行數據將被阻塞,直到Session 1提交或者回滾數據
Session 1: update employees set salary = 612 where employee_id = 100步驟三:再次執行步驟一的操作
Session 1: SELECT employee_id, salary FROM employees WHERE employee_id IN (100, 101); EMPLOYEE_ID SALARY ------------------------- 100 612 101 600 Session 2: SELECT employee_id, salary FROM employees WHERE employee_id IN (100, 101); EMPLOYEE_ID SALARY ------------------------- 100 512 101 600 Session 3: SELECT employee_id, salary FROM employees WHERE employee_id IN (100, 101); EMPLOYEE_ID SALARY ------------------------- 100 512 101 600Session 1的結果是它更新後的數據,而其他兩個session任然是舊數據。
UPDATE hr.employees SET salary = salary + 100 WHERE employee_id = 101;步驟五:再次執行步驟1的查詢
Session 1: SELECT employee_id, salary FROM employees WHERE employee_id IN (100, 101); EMPLOYEE_ID SALARY ------------------------- 100 612 101 600 Session 2: SELECT employee_id, salary FROM employees WHERE employee_id IN (100, 101); EMPLOYEE_ID SALARY ------------------------- 100 512 101 700 Session 3: SELECT employee_id, salary FROM employees WHERE employee_id IN (100, 101); EMPLOYEE_ID SALARY ------------------------- 100 512 101 600