原因:
数据库是一个多用户使用的共享资源。当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。
原理:
1.UPDATE/DELETE操作会将RS锁定,直至操作被COMMIT或者ROLLBACK; 若操作未COMMIT之前其他session对同样的RS做变更操作,则操作会被hold,直至前session的UPDATE/DELETE操作被COMMIT; 2.session内外SELECT的RS范围 前提:INSERT、UPDATE操作未COMMIT之前进行SELECT; 若在同一session内,SELECT出来的RS会包括之前INSERT、UPDATE影响的记录; 若不在同一session内,SELECT出来的RS不会包括未被COMMIT的记录; 3.SELECT.... FOR UPDATE [OF cols] [NOWAIT/WAIT] [SKIP LOCKED] OF cols:只锁定指定字段所在表的RS,而没有指定的表则不会锁定,只会在多表联合查询时出现; NOWAIT:语句不会hold,而是直接返回错误ORA-00054: resource busy and acquire with NOWAIT specified; WAIT N:语句被hold N秒,之后返回错误ORA-30006: resource busy; acquire with WAIT timeout expired; SKIP LOCKED:不提示错误,而是直接返回no rows selected; 以上几个选项可以联合使用的,比较推荐的有: SELECT.... FOR UPDATE NOWAIT:对同一RS执行该SQL时,直接返回错误; SELECT.... FOR UPDATE NOWAIT SKIP LOCKED:对同一RS执行该SQL时,直接返回空行; PS:当RS被LOCK住之后,只对同样请求LOCK的语句有效,对无需LOCK的SELECT语句并没有任何影响;解决办法:
oracle数据中删除数据时提示“记录被另一个用户锁住” 解决方法:
1、查看数据库锁,诊断锁的来源及类型: select object_id,session_id,locked_mode from v$locked_object; 或者用以下命令: select b.owner,b.object_name,l.session_id,l.locked_mode from v$locked_object l, dba_objects b where b.object_id=l.object_id
2、找出数据库的serial#,以备杀死: select t2.username,t2.sid,t2.serial#,t2.logon_time from v$locked_object t1,v$session t2 where t1.session_id=t2.sid order by t2.logon_time;
3、杀死该session alter system kill session 'sid,serial#'