程序中每隔几秒刷新时间,如果间隔大于5分钟,则说明程序1宕机,程序而则获取权限继续处理。
一般还可以选择在程序中发心跳。
create or replace procedure authorwrflag
(
p_market integer,
p_type varchar2
)
is
plasttime integer;
phour integer;
pminute integer;
psecond integer;
begin
select to_number(to_char(sysdate,'hh24')) into phour from dual;
select to_number(to_char(sysdate,'mi')) into pminute from dual;
select to_number(to_char(sysdate,'ss')) into psecond from dual;
plasttime := phour*10000 + pminute*100 + psecond;
update T_SYS_WRCTRL set lasttime=plasttime where market=p_market and type=p_type ;
commit;
-- DBMS_OUTPUT.put_line(to_char(sysdate,'hh24'));
-- DBMS_OUTPUT.put_line(to_char(sysdate,'mi'));
-- DBMS_OUTPUT.put_line(to_char(sysdate,'ss'));
end;
create or replace procedure getwrflag
(
p_market integer, -- 市场
p_type varchar2 , -- 类型
p_canwr out integer -- 是否有权限, 0:无,1:可以,2:正在写
)
is
-- 获取时间单元
phour integer;
pminute integer;
psecond integer;
p_status integer ; -- 状态
p_nowtime integer ; -- 现在时间
p_nowdate integer; -- 现在日期
p_lastdate integer ; -- 最近日期
p_lastupdatetime integer ; -- 最近时间
p_rowcounttemp integer ; --影响的行数
p_errorcode integer ; --错误码
p_errormsg varchar2(32); -- 错误信息
begin
select status ,lasttime, lastdate into p_status ,p_lastupdatetime ,p_lastdate
from T_SYS_WRCTRL
where market=p_market and type=p_type;
p_rowcounttemp := sql%rowcount ; -- 判断影响的行数
-- 获取时间
select to_number(to_char(sysdate,'hh24')) as hour into phour from dual;
select to_number(to_char(sysdate,'mi')) as minute into pminute from dual;
select to_number(to_char(sysdate,'ss')) as second into psecond from dual;
p_nowtime := phour*10000 + pminute*100 + psecond;
-- 获取日期
p_nowdate:=extract(year from sysdate)*10000 + extract(month from sysdate)*100 + extract(day from sysdate);
-- 判断影响的行数
if p_rowcounttemp = 0
then
p_errorcode := -1 ; p_errormsg := 'not init table'; p_canwr :=0;
elsif (p_status=1) and (p_nowdate<=p_lastdate) --现在的日期 <= 数据库中的日期
then --已写盘
p_errorcode := 0 ; p_errormsg := 'OK'; p_canwr:=0;
elsif (p_nowdate>p_lastdate) or --不是当日
(p_status=0) or
(p_status=2 and (p_nowtime-p_lastupdatetime)>500)
then --原已获得权限 --其他服务器写盘超时, 5min
update T_SYS_WRCTRL set status=2,lasttime=p_nowtime,lastdate=p_nowdate where market=p_market and type=p_type;
if sqlcode <> 0 then
p_errorcode := -3 ; p_errormsg := 'update err'; p_canwr:=2;
else
p_errorcode := 0 ; p_errormsg := 'Ok'; p_canwr:=1;
end if;
elsif p_status=2 --其他服务器正在写盘--让外部循环尝试获取权限
then
p_errorcode := 0 ;p_errormsg := 'Ok'; p_canwr:=2;
else
p_errorcode := -5 ; p_errormsg := 'unkown err'; p_canwr:=0;
end if;
-- update是否执行成功
if sqlcode = 0 then
commit ; --提交
else
rollback; -- 回滚
end if;
-- 输出内容
DBMS_OUTPUT.put_line(p_errorcode);
DBMS_OUTPUT.put_line(p_errormsg);
end;
表结构:
create table T_SYS_WRCTRL (
market integer not null, --市场
type varchar2(16) not null, --类别 SBA1,SBA2...
status integer null, --状态,0:未写或写失败,1:已写。2:正在写
lasttime integer null, --更新时间,写盘时心跳,status=2时使用,若超时则修改STATUS,以防服务器写盘过程中当机
lastdate integer null,
constraint PK_T_SYS_WRCTRL primary key (market, type)
)