select sid,type,id1,lmode,request,block from v$lock l where sid in (select session_id from v$locked_object) and type in (‘TM‘, ‘TX‘) order by 1;
读永远不会阻止写。但有唯一的一个例外,就是select ...for update。
写永远不会阻塞读。
当一行被修改后,Oracle通过回滚段提供给数据的一致性读。
注意:以上说明的读和写不会互相阻塞是指在DML锁级别不会,但读写之间依然会发生数据库内部闩锁的争用。具体详见数据库内部闩锁的博文。
2.DDL锁
重点:DDL是保护表结构定义的。
当DDL命令发出时,Oracle会自动在被处理的对象上添加DDL锁定,从而防止对象被其他用户所修改。当DDL命令结束以后,则释放DDL锁定。DDL锁定不能显式的被请求,只有当对象结构被修改或者被引用时,才会在对象上添加DDL锁定。
需要注意的是DDL总会提交,即便是执行不成功也是如此,因此如果在事务中执行了DDL语句会导致所有事物被提交。验证很容易,在一个窗口执行一条delete然后执行DDL,你会发现记录被不可逆转的删除了,RollBack无效。因此针对事务中的DDL请务必使用自治事务实现。
DDL锁有3种:(第一种就是X模式的TM锁)
2.1 排他DDL锁
一般对表的DDL语句都会获取一个X模式的TM锁,这是为什么在表结构更改时只能查询不能修改的原因。
2.2 共享DDL锁
共享DDL锁的常见情形为创建存储过程时,会尝试为所有涉及到的表添加共享DDL锁,这会允许类似的DDL操作并发,但会阻止所有想要获取排他DDL锁的会话(即更改表结构的会话)。
2.3 可中断解析锁
会话解析一条语句时,对于该语句引用的每一个对象都会施加解析锁,这个目的是如果以某种方式删除或修改了引用对象,可以将共享池中已经解析的缓存语句无效刷出。
3.内部闩锁机制(略)
详见博文,关于Oracle buffer pool/shared pool的内部闩锁机制的实现。