您的位置:首页 > 其它

锁机制

2016-01-08 11:55 399 查看
业务场景:

提交流程接口,每次调用该接口会将当前流程提交至下一节点。需要避免重复提交流程


解决思路:

1.sychonized 锁

不适用     ---  sychonized锁  当代码块被加锁时,后面的请求要等待执行完后才可以执行(排队)。但当短时间内产生同一请求,会重复提交


2.redis缓存

进入方法

---判断缓存中是否有当前流程实例化编号

没有---向REDIS缓存 放入数据

有---拒绝

方法结束时清空缓存


(需要考虑负载均衡,如果有负载均衡要看是不是有集群级别的redis缓存配置)

3.数据库实现加锁

新建加锁表, 保存加锁对象、加锁时间、加锁时长、过期时间

存储过程如下:

/***********************************************
*comment: 取得一个锁,如加锁成功 p_expire_date 不为空,否则 p_expire_date 为空
************************************************/
PROCEDURE  LOCK(
target_id    IN  VARCHAR2,        -- 锁 ID
lock_mins    IN  NUMBER,         -- 加锁分钟数
expire_date  OUT DATE             -- 锁失效时间

) IS
v_lock_date DATE := SYSDATE;
v_type_count  number(3);
v_lock_mins NUMBER := p_lock_mins;
v_expire_date DATE;
BEGIN
p_expire_date := NULL;
IF p_lock_mins IS NULL OR p_lock_mins <= 0 THEN
v_lock_mins := 30;
END IF;
v_expire_date := v_lock_date + (lock_mins / 24 / 60 /60);
UPDATE lock l
SET l.lock_date = v_lock_date,
l.expire_date = v_expire_date,
l.updated_by   = 'sys',
l.DATE_UPDATED  = sysdate
WHERE l.EXPIRE_DATE < SYSDATE
AND l.TARGET_ID = target_id;
IF SQL%FOUND THEN
p_expire_date := v_expire_date;
ELSE
BEGIN
select count(1)
into v_type_count
from wf_lock_mas t
where t.target_id = p_target_id;
if v_type_count = 0 then
INSERT INTO lock
(pk_lock,
target_id,
lock_date,
expire_date,
created_by,
DATE_CREATED,
updated_by,
DATE_UPDATED)
values
(seq_id,
target_id,
v_lock_date,
v_expire_date,
'sys',
sysdate,
'sys',
sysdate);
p_expire_date := v_expire_date;
end if;
if v_type_count > 0 then
p_expire_date := null;
end if;
exception
when dup_val_on_index then
p_expire_date := null;
--RETURN;
END;
END IF;

ENDLOCK;


对应的解锁sql

<!-- 解锁-->
UPDATE SYC_BSE_QL l
SET l.EXPIRE_DATE = sysdate - 0.00001,
l.UPDATED_BY = 'yxd-pms',
l.UPDATED_DATE = SYSDATE
WHERE l.EXPIRE_DATE > SYSDATE
AND l.TARGET_ID = #p_target_id#
AND l.TARGET_TYPE = #p_target_type#
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: