一、oracle默认在update时是行锁。但如果update的where条件中有函数在使用,这时是行锁还是表锁?
举例:
SQL> update emp set sal=8000 where empno=7369;
1 row updated
SQL> select sid,type,lmode from v$lock where sid=146;
SID TYPE LMODE
---------- ---- ----------
146 TM 3
146 TX 6
SQL> rollback;
Rollback complete
SQL> update emp set sal=8000 where to_char(hiredate,'yyyy-mm-dd')='1980-12-17';
1 row updated
SQL> select sid,type,lmode from v$lock where sid=146;
SID TYPE LMODE
---------- ---- ----------
146 TM 3
146 TX 6
SQL> rollback;
Rollback complete
SQL>
在对表一行或多行进行更新时,会在行上产生行级锁,其他会话就不能对锁定的行进行DML操作,
同时,会在表上产生一个表锁,表锁是阻止对表进行DDL操作,比如增删列,删除表等等。
所以全表更新和带条件更新都产生两种锁。
二、for update 存在的问题:
两个update的问题:
1. 如果在for update一个行后 网络断掉 这个行会在什么时候解锁
2. 如何查询一个行是否被锁定 如果需要for update时 是否要事先判断下这个行是否被锁定 防止重复加锁
1->select .... from update是悲观加锁,你断开连接了意味着你的会话异常关闭了,其余的要由服务器来释放了。具体锁定时间不知道,一般需要手工解锁。
2->不需要判断,如果已经被锁,ORACLE会提示你,资源正忙。但可以用select .... from update nowait,不需要等待。如果已被锁,立即失败,如果未被锁,立即成功锁定!
1->是的。如果很多session断开了,服务器确实有很多异常会话。对服务器来说,它并未能立即感知客户端异常断开,所以它依然会保留锁。此时需要手工kill session。DBA就是你提到的这个专人,这些工作的是他们的分内事。
2->不是必须加,看你是否能接受等待了。如果你不希望等待,就加之。