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