如何在 DB2 存储过程中捕获 ctrl-c 行为



我正在使用DB2 11.5.

我有一个存储过程,它将运行一些复杂的任务。 在运行任务之前,它将首先从日志表中检查作业是否已在运行,如果是,则发出SQLSTATE 75002错误测量信号。

如果尚未运行,它将插入状态为RUNNING的作业记录,然后运行任务。

完成后,它将状态更新为FINISHED

CREATE OR REPLACE PROCEDURE WORK.TEST_SP()
P1: BEGIN

if exists(select 1 from db2inst1.job_log where job='abc' and status='RUNNING' and date=current date) then
SIGNAL SQLSTATE '75002' SET MESSAGE_TEXT = 'Job abc is already running, please wait for it to finish';
end if;
insert into db2inst1.job_log values ('abc', 'RUNNING', current date);
commit;
-- Some complex tasks here
call dbms_lock.sleep(120);
update db2inst1.job_log set job_status='FINISHED' where job_name='abc' and job_date=current date
commit;
END P1

我的问题是,当用户按下在复杂任务运行时中止存储过程的ctrl-c时,如何处理 sigint?

我希望它在发生ctrl-c时更新job_status以ABORTED,以便作业不会永远"运行"。

#Edit 1

用户在安装了 db2 客户机的本地机器上使用 Windows.bat文件运行存储过程。

@echo off
@if ""%DB2CLP%""=="""" db2cmd /c /i /w ""%0"" && goto :EOF
db2 connect to mydb user db2inst1 using abc123
db2 "call WORK.TEST_SP()"
IF ERRORLEVEL 1 (echo Job failed) else (echo Job done)
db2 connect reset > nul
pause

如果您的 MS-Windows 批处理文件被 Control-C 或其他信号中断,则默认情况下,该应用调用的任何已启动/正在运行的存储过程将继续运行。 存储过程将不知道客户端应用程序已终止。因此,批处理文件 (cmd/bat) 将终止,但任何当前运行的存储过程将继续在 Db2 服务器上执行。

不能将操作系统信号直接发送到 Db2-LUW 存储过程,因为它们在后台的 Db2 服务器上运行,并且通常由与执行call的用户标识不同的帐户拥有。

存储过程应有自己的条件处理程序、退出处理程序或撤消处理程序。通常,如果发生硬错误,而过程本身无法恢复,则希望发出rollback。但是 Db2 本身会为特定的 sqlcode 发出回滚(例如 -911 )。

Db2-LUW 还具有应用程序在特定情况下可能使用的sysproc.cancel_work过程。有关详细信息,请参阅知识中心。如果启用了 WLM(工作负载管理)或等效项,则存储过程受其资源消耗配置的约束,并且 WLM 还提供wlm_cancel_activity例程。

在 SP.

存储过程是如何运行的?从命令行(db2)?如果是,在哪些操作系统上?

例如,如果命令在 Linux 上从bash运行,则可以在用户按 Ctrl-Cmyfunc使用 Bash 中的trap myfunc SIGINT来运行自定义 Bash 函数。 然后,myfunc可以更改作业状态。

在Windows上,如果您从普通.bat文件切换到Powershell,您将拥有更多控制权。一些相关的堆栈溢出问题:

  • 批处理脚本,如果用户按 Ctrl+C 在退出之前执行命令
  • 优雅地停在Powershell中

最新更新