需要在PL SQL中同时在不同会话中运行的不同SP写入单个日志文件

时间:2018-07-13 16:36:34

标签: oracle plsql oracle12c

我想由运行在不同会话中的多个SP写入单个日志文件(每天创建)。

这就是我所做的。

create or replace PKG_LOG:
procedure SP_LOGFILE_OPEN
      step 1) Open the logfile:
      LF_LOG      := UTL_FILE.FOPEN(LV_FILE_LOC,O_LOGFILE,'A',32760);
end SP_LOGFILE_OPEN;

procedure SP_LOGFILE_write
      step 1) Write the logs as per application need:
      UTL_FILE.PUT_LINE(LF_LOG,'whatever i want to write');
      step 2) Flush the content as i want to logs to be written in real time.
      UTL_FILE.FFLUSH(LF_LOG);
end SP_LOGFILE_write;

现在,无论何时在任何存储过程中我都想先写入日志,我都会先调用SP_LOGFILE_OPEN,然后再调用SP_LOGFILE_write(需要多少次)。

问题是,如果有两个存储过程,则说SP1和SP2。如果他们两个都尝试同时打开它,则它永远不会出现错误或等待另一个完成。而是在执行SP1和SP2的两个会话中打开它。 SP1的内容(如果首先开始运行)将完全写入日志文件,但是SP2中的内容将部分写入日志文件。仅当SP1的执行停止时,SP2才开始写入。由于FFLUSH,它试图写入日志文件的SP2的初始内容也丢失了。 根据我的要求,我不想在运行SP1时丢失第二个SP2的内容。 有任何建议请。我不想实时放弃FFLUSH的想法。 谢谢。

2 个答案:

答案 0 :(得分:0)

您可以使用DBMS_LOCK获得自定义锁,或者等到锁可用后再进行写操作,然后释放锁。它必须被序列化。

但是这会使您的并发问题甚至更糟。基本上,您说的是对此过程的所有调用都必须排成一行并一个接一个地处理。请记住,磁盘I / O速度很慢,因此您的数据库现在仅与磁盘一样快。

答案 1 :(得分:0)

您的主意不好。无需直接写入文件,只需将一条日志消息排队到Oracle高级队列中,并创建一个非常频繁(每隔几秒钟)运行的作业以从AQ出队。这是作业实际写入文件的调用过程。这样,您可以同步尝试同时登录同一文件的不同SP执行。实际的日志记录是由作业调用的单个SP进行的。