/*************************************************
四、主题: 锁——避免重复启动同一程序
锁 捕捉唯一性
*************************************************/
=============================================================================
CREATE TABLE TEST5
(
ID NUMBER(5),
NAME VARCHAR(10),
UIID NUMBER(5)
);
INSERT INTO TEST5 VALUES(1,‘A‘,NULL);
INSERT INTO TEST5 VALUES(2,‘B‘,NULL);
INSERT INTO TEST5 VALUES(3,‘C‘,NULL);
INSERT INTO TEST5 VALUES(4,‘Aa‘,1);
INSERT INTO TEST5 VALUES(5,‘Ab‘,1);
=============================================================================
4.1.判断是否是否加上了锁
--SESSION_1
UPDATE TEST5
SET NAME = NAME;
不提交,然后新打开一个窗口,执行下面语句:
--SESSION_2
SELECT * FROM TEST5; --能正常获取数据
SELECT * FROM TEST5 FOR UPDATE NOWAIT; --资源站正忙,无法获取数据,说明SESSION_1 已经加上了锁。
--若SESSION_1 提交了,则 SESSION_2 就能得到数据
4.2.在得知被锁后,退出不执行后续语句
SESSION_1 不提交修改。
--SESSION_2
-----------------------------------------------
DECLARE
E_FAILED_TO_LOCK EXCEPTION;
V_ID NUMBER;
PRAGMA EXCEPTION_INIT (E_FAILED_TO_LOCK,-54);
BEGIN
SELECT ID INTO V_ID FROM TEST5 WHERE ID=1 FOR UPDATE NOWAIT;
EXCEPTION
WHEN E_FAILED_TO_LOCK THEN
RAISE_APPLICATION_ERROR(-20004,‘IT‘S LOCKED!‘);
null;
END;
/
-----------------------------------------------
--提示:IT‘S LOCKED!
若想执行正确,可以先提交SESSION_1.
4.3. 与上面一样,利用主键,防止重复记录。
若是INSERT INTO 时,主键冲突,则EXCEPTION 执行NULL,忽略异常继续前进。
--此处,一般用MERGE INTO 来解决最好。
4.4.获取机器IP\终端号\SID等
SELECT USERENV(‘SESSIONID‘) FROM DUAL;
SELECT USERENV(‘TERMINAL‘) FROM DUAL;
SELECT SYS_CONTEXT(‘USERENV‘,‘IP_ADDRESS‘) FROM DUAL;
SELECT SYS_CONTEXT(‘USERENV‘,‘CURRENT_USER‘) FROM DUAL;
SELECT SID FROM V$MYSTAT WHERE ROWNUM=1;
4.5.构造检查机制,防止失败执行报错,给出提示。
4.锁——避免重复启动同一程序