Oracle锁1:DML锁
DML锁有行锁(Row Locks,TX)和表锁(Table Locks,TM),不同的DML操作会自动请求对应的锁。
行锁(Row Locks,TX)
行锁防止两个事务修改同一行数据,当一个事务修改一行数据时,数据库总是为修改的行加一个排它锁以至于其它事务无法修改该行,只有当事务执行了commit或者roll back操作后,数据库才会释放对应的锁。行锁是小粒度的锁,为应用提供了最大限度的并行修改数据的能力。
当一个事务获取了一个行锁,那么这个事务也需要获取这行数据所在表的表锁,表锁阻止有冲突的DDL操作,即数据库会自动的为更新的行添加一个排它锁,并为行所在的表添加一个子排它锁。
行锁和并发
首先创建下面的表格,并初始化数据:
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
行锁的存储
当一个事务结束时,事务ID保留在block header中,如果另一个事务想修改一行数据,那么它用这个事务ID判定这个锁是否是激活的。如果锁是激活的,那么当锁被释放时,该事务的session将被通知,否则,事务获取这个锁。
表锁(Table Locks,TM)
Row Share(RS)
Row Exclusive Table Lock(RX)
Share Table Lock(S)
Share Row Exclusive Table Lock(SRX)
Exclusive Table Lock(X)
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。