Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oracle PL/SQL:如何检测过程是否已经在运行?_Oracle_Procedure - Fatal编程技术网

Oracle PL/SQL:如何检测过程是否已经在运行?

Oracle PL/SQL:如何检测过程是否已经在运行?,oracle,procedure,Oracle,Procedure,请假设我们在一个包中有一个过程: MY_PACKAGE.MY_PROCEDURE 可以从许多用户启动此过程 如何修改该过程,以检测该过程是否正在运行,因为它是从另一个用户启动的 最安全的检测方法是什么 谢谢你考虑我的要求 编辑01:这取决于为什么您需要知道某个过程是否已经在运行==>如果该过程当前正在运行,它不会再次启动。根据其他人提到的内容和对DBMS_LOCK包头的快速阅读,您似乎可以使用各种DBMS_LOCK例程来完成您试图完成的任务。如果我正确地阅读了标题注释,您可能希望调用ALLOC

请假设我们在一个包中有一个过程:

MY_PACKAGE.MY_PROCEDURE
可以从许多用户启动此过程

如何修改该过程,以检测该过程是否正在运行,因为它是从另一个用户启动的

最安全的检测方法是什么

谢谢你考虑我的要求


编辑01:这取决于为什么您需要知道某个过程是否已经在运行==>如果该过程当前正在运行,它不会再次启动。

根据其他人提到的内容和对DBMS_LOCK包头的快速阅读,您似乎可以使用各种DBMS_LOCK例程来完成您试图完成的任务。如果我正确地阅读了标题注释,您可能希望调用ALLOCATE_UNIQUE来获取一个唯一的、命名的锁的句柄,然后在锁定模式设置为“x”Exclusive的情况下调用REQUEST来尝试获取锁。如果请求调用返回0,则可以继续运行例程。完成后,调用RELEASE以使锁可供下一个调用方使用


祝你好运。

根据其他人提到的内容和对DBMS_LOCK包头的快速阅读,您似乎可以使用各种DBMS_LOCK例程来完成您要做的事情。如果我正确地阅读了标题注释,您可能希望调用ALLOCATE_UNIQUE来获取一个唯一的、命名的锁的句柄,然后在锁定模式设置为“x”Exclusive的情况下调用REQUEST来尝试获取锁。如果请求调用返回0,则可以继续运行例程。完成后,调用RELEASE以使锁可供下一个调用方使用

祝您好运。

您可以使用此软件包获取此类信息

PROCEDURE MY_PROCEDURE(..) IS
BEGIN
DBMS_APPLICATION_INFO.SET_CLIENT_INFO('MY_PACKAGE.MY_PROCEDURE running');

   ... All your stuff

DBMS_APPLICATION_INFO.SET_CLIENT_INFO(NULL);
EXCEPTION
  WHEN OTHERS THEN
    DBMS_APPLICATION_INFO.SET_CLIENT_INFO(NULL);
    RAISE;
END MY_PROCEDURE;
要进行检查,可以选择V$会话视图:

SELECT * 
FROM v$session 
WHERE client_info = 'MY_PACKAGE.MY_PROCEDURE running';
如果您得到任何记录,则该过程正在运行。

您可以使用该包获取此类信息

PROCEDURE MY_PROCEDURE(..) IS
BEGIN
DBMS_APPLICATION_INFO.SET_CLIENT_INFO('MY_PACKAGE.MY_PROCEDURE running');

   ... All your stuff

DBMS_APPLICATION_INFO.SET_CLIENT_INFO(NULL);
EXCEPTION
  WHEN OTHERS THEN
    DBMS_APPLICATION_INFO.SET_CLIENT_INFO(NULL);
    RAISE;
END MY_PROCEDURE;
要进行检查,可以选择V$会话视图:

SELECT * 
FROM v$session 
WHERE client_info = 'MY_PACKAGE.MY_PROCEDURE running';

如果您得到任何记录,则该过程正在运行。

我可能只需要创建一个至少存储用户名、包、过程和开始时间的表,然后更改该过程,在调用该过程时将行插入表中,然后将其删除。不过我很期待看到其他人的建议!嗯,或者,您可以使用dbms_应用程序_信息调用来设置模块和操作,然后在v$session中可以看到每个会话都在做什么。这将取决于为什么你需要知道一个进程是否已经在运行。@Boneist:我想你仍然有一个竞赛条件。我不知道有哪种同步原语可以在PL/SQL中访问,但我的知识还远远不够全面。Oracle PL/SQL API的任何地方都有类似互斥的东西吗?我记得在我以前的工作中有一个人告诉我他们使用Oracle上下文功能来实现类似的功能。看看这篇文章:它一定是“全局访问”上下文,您可以在其中简单地为所有想要的参数设置名称-值耦合。不幸的是,我现在无法尝试,但这看起来很有希望。另一方面使用状态表和使用自治事务写入状态表这样简单的解决方案更有意义:@Bob Jarvis:dbms_lock.request功能有一个互斥函数,但不确定OP试图实现什么:等待另一个完成,或者在同一时间使用相同的过程执行其他操作。如果这是出于等待的目的,那么使用互斥可以是解决方案。我可能只需要创建一个至少存储用户名、包、过程和开始时间的表,然后更改过程,在调用该表时将行插入表中,然后将其删除。不过我很期待看到其他人的建议!嗯,或者,您可以使用dbms_应用程序_信息调用来设置模块和操作,然后在v$session中可以看到每个会话都在做什么。这将取决于为什么你需要知道一个进程是否已经在运行。@Boneist:我想你仍然有一个竞赛条件。我不知道有哪种同步原语可以在PL/SQL中访问,但我的知识还远远不够全面。Oracle PL/SQL API的任何地方都有类似互斥的东西吗?我记得在我以前的工作中有一个人告诉我他们使用Oracle上下文功能来实现类似的功能。看看这篇文章:它一定是“全局访问”上下文,您可以在其中简单地为所有想要的参数设置名称-值耦合。不幸的是,我现在无法尝试,但这看起来很有希望。另一方面,使用简单的解决方案,如使用状态表并使用自治事务写入状态表,则更有意义:@Bob Jarvis:有一个带有dbms_lock.request功能的互斥锁功能,但不确定OP试图实现什么:等待另一个完成或执行
那时候还有其他的事情,用同样的程序。如果这是出于等待的目的,那么使用互斥可能是解决方案谢谢您的示例代码。如果我在异常情况下忘记设置NULL呢?从Oracle会话注销后,是否有方法重置?客户端信息与会话相关,因此当会话关闭时,客户端信息当然也会消失。感谢您提供示例代码。如果我在异常情况下忘记设置NULL呢?从Oracle会话注销后,是否有方法重置?客户端信息与会话相关,因此当会话关闭时,客户端信息当然也会消失。