【问题标题】:How to catch ctrl-c behavior in DB2 stored procedure如何在 DB2 存储过程中捕获 ctrl-c 行为
【发布时间】:2021-08-09 13:59:19
【问题描述】:

我正在使用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 时,我该如何处理在复杂任务运行时中止存储过程的信号?

我希望它在发生ctrl-c 时将job_status 更新为ABORTED,这样作业就不会永远“运行”。

#编辑 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

【问题讨论】:

  • 您不能将操作系统信号发送到 Db2 存储过程(例如,您不能将 Control-C 发送到 Db2 存储过程)。如果客户端工作站上的调用应用程序被 Control-C 中断,则客户端应用程序可能会选择停止,但由该应用程序启动的任何已经运行的存储过程将继续运行(默认情况下)并且不知道客户端应用程序已终止。

标签: sql stored-procedures db2


【解决方案1】:

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

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

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

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

【讨论】:

    【解决方案2】:

    在 SP 中无法做到这一点。
    在强制调用者离开数据库、取消活动和一些其他条件(例如,日志已满)时,控制不会传递给 SP 中定义的异常处理程序。

    所以,不要将任何标志/状态管理逻辑放入 SP 异常处理程序中。

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

      • 存储过程由windows .bat 文件触发。 .bat文件只是连接数据库并执行db2 "call WORK.TEST_SP()"
      猜你喜欢
      • 1970-01-01
      • 2015-11-27
      • 1970-01-01
      • 2011-03-08
      • 1970-01-01
      • 2019-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多