含有單一管線的快取訊息
關於使用單一管路快取訊息
DBMS_PIPE
套裝軟體在 Autonomous Database 上具有擴充功能,可支援單一管道。
DBMS_PIPE
中的單一管:
-
使用單一管路訊息提供自訂資料的記憶體內快取。
-
支援快取和擷取最多 32,767 個位元組的自訂訊息。
-
支援透過並行讀取跨多個資料庫階段作業共用快取訊息。這可提供高傳輸量,並支援跨資料庫階段作業並行讀取訊息。
-
支援唯讀和讀寫資料庫。
-
支援數種快取無效化方法:
- 由使用者控制的明確快取無效化。
- 使用者指定的時間間隔之後的快取無效化 (秒)。此無效驗證方法是由訊息寄件者所控制,使用
shelflife
參數,而非由訊息讀取者所控制。這可避免常見的陷阱,因為讀取器使用快取不正確。
關於標準管和單孔管
DBMS_PIPE 套裝程式允許兩個或多個資料庫階段作業使用記憶體內訊息進行通訊。管線功能有數個應用程式,例如外部服務介面、除錯、獨立交易和警示。請參閱 Oracle Database 19c PL/SQL Packages and Types Reference 中的 DBMS_PIPE 或 Oracle Database 23ai PL/SQL Packages and Types Reference ,瞭解詳細資訊。

database-pipe-messages-singleton-pipes.eps 圖解描述
Singleton Pipe 可以是任何支援的 DBMS_PIPE
類型:
- 隱含管:使用
DBMS_PIPE.SEND_MESSAGE
函數以不明的管路名稱傳送訊息時,會自動建立訊息。 - 明確管線:使用
DBMS_PIPE.CREATE_PIPE
函數與使用者指定的管線名稱建立。 - 公用管道:任何具備
DBMS_PIPE
套裝軟體EXECUTE
權限的使用者均可存取。 - 私人管道:具有與管道建立者相同之使用者的階段作業可存取。
Singleton Pipes 可讓您在 Autonomous Database 執行處理的記憶體中快取單一訊息。
以下顯示使用單一管道的一般工作流程。

singleton-pipe-workflow.eps 圖解描述
單一管概觀和功能
-
單一訊息
- Singleton Pipe 可在管道中快取一則訊息,因此名稱為 "singleton"。
- Singleton Pipe 中的訊息可由多個欄位組成,總訊息大小為 32,767 個位元組。
DBMS_PIPE
支援使用DBMS_PIPE.PACK_MESSAGE
程序將多個屬性封裝在訊息中。- 對於公用單一管路,任何具備
DBMS_PIPE
套裝程式執行權限的資料庫階段作業都可以接收訊息。 - 若為「專用單一管」,階段作業可以接收與「單一管」建立者相同之使用者的訊息。
- 讀取的訊息處理量上限
- Singleton Pipes 會將訊息快取到管中,直到該訊息失效或被清除為止。資料庫階段作業可以並行從 Singleton Pipe 讀取訊息。
- 從 Singleton Pipe 接收訊息是一項無阻塞的作業。
- 訊息快取
- 使用
DBMS_PIPE.SEND_MESSAGE
在單一管中快取訊息。 - 如果 Singleton Pipe 中有現有的快取訊息,則
DBMS_PIPE.SEND_MESSAGE
會覆寫先前的訊息,以便只在 Singleton Pipe 中保留一則訊息。
- 使用
- 訊息無效
- 明確無效驗證:使用
DBMS_PIPE.PURGE
程序清除管道,或使用DBMS_PIPE.SEND_MESSAGE
覆寫訊息。 - 自動無效驗證:訊息可以在指定的
shelflife
時間過後自動失效。
- 明確無效驗證:使用
- 資料庫記憶體沒有收回
- Singleton Pipes 不會從 Oracle Database 記憶體收回。
- 明確的 Singleton Pipe 會繼續位於資料庫記憶體中,直到使用
DBMS_PIPE.REMOVE_PIPE
移除為止,或重新啟動資料庫為止。 - 「隱含單一管」會保留在資料庫記憶體中,直到管中有一個快取訊息為止。
單一管路作業
操作 | DBMS_PIPE 函數或程序 |
---|---|
建立明確的單一管路 |
|
在 Singleton Pipe 中快取訊息 |
PACK_MESSAGE Procedures in Oracle Database 19c PL/SQL Packages and Types Reference or Oracle Database 23ai PL/SQL Packages and Types Reference |
從 Singleton Pipe 讀取快取訊息 |
RECIEVE_MESSAGE 函數、 UNPACK_MESSAGE 程序,位於 Oracle Database 19c PL/SQL Packages and Types Reference 或 Oracle Database 23ai PL/SQL Packages and Types Reference |
刪除 Singleton Pipe 中的訊息 |
Oracle Database 19c PL/SQL Packages and Types Reference 或 Oracle Database 23ai PL/SQL Packages and Types Reference 中的 PURGE 程序 |
移除明確的單一管路 |
REMOVE_PIPE Function in Oracle Database 19c PL/SQL Packages and Types Reference or Oracle Database 23ai PL/SQL Packages and Types Reference |
使用快取功能自動重新整理快取訊息
DBMS_PIPE
套裝程式可讓您使用使用者定義的快取函數自動填入「單一管線」訊息。
依照預設,當訊息因「單一管」明確或隱含無效驗證而失效之後,後續的 DBMS_PIPE.RECEIVE_MESSAGE
將不會收到任何訊息。若要新增訊息至管道,必須透過呼叫 DBMS_PIPE.SEND_MESSAGE
明確快取訊息。若要避免此情況,當您從「單一管」讀取時沒有可用的訊息,可以定義快取函數。定義快取函數後,當您收到下列情況的訊息時,會自動呼叫快取函數:
- Singleton Pipe 是空的。
- 當 Singleton Pipe 中的訊息因為經過
shelflife
時間而無效時。
若要使用快取函數,請定義快取函數並包含 cache_func
參數與 DBMS_PIPE.RECEIVE_MESSAGE
。使用者定義的快取函數提供下列各項:
- 使用
DBMS_PIPE.RECEIVE_MESSAGE
從單一管路讀取訊息時,可以指定快取函數。 - 當單一管中沒有訊息時,
DBMS_PIPE.RECEIVE_MESSAGE
會呼叫快取函數。 - 訊息
shelflife
時間過後,資料庫會自動在「單一管線」中填入新訊息。
使用快取函數可簡化單一管的使用。您不需要處理從空管道接收訊息的失敗案例。此外,快取功能可確保從單一管路讀取訊息時不會遺漏快取記憶體,以最大限度地使用快取訊息。

auto-cache-refresh-cache-function.eps 圖解描述
當您定義快取函數時,函數名稱必須完全符合擁有者綱要:
OWNER.FUNCTION_NAME
OWNER.PACKAGE.FUNCTION_NAME
定義具有下列簽章的快取函數:
CREATE OR REPLACE FUNCTION cache_function_name(
pipename IN VARCHAR2
) RETURN INTEGER;
快取函數內的一般作業為:
- 使用
DBMS_PIPE.CREATE_PIPE
建立明確管的單一管。 - 建立要在單一管中快取的訊息。
- 將訊息傳送至快取函數中指定的管道,選擇性地為隱含訊息指定
shelflife
。
若要使用快取函數,呼叫 DBMS_PIPE.RECEIVE_MESSAGE
的目前階段作業使用者必須具有執行快取函數的必要權限。
請參閱 RECIEVE_MESSAGE 函數,瞭解有關定義快取函數的詳細資訊。
建立明確的單一管路
描述使用指定的管名 (明確的 Singleton 管) 建立 Singleton 管的步驟。
首先,在此範例中,請建立 receive_message
協助程式函數來重複呼叫 DBMS_PIPE.RECEIVE_MESSAGE
。這可讓您測試單一管路功能。
CREATE OR REPLACE FUNCTION msg_types AS
TYPE t_rcv_row IS RECORD (c1 VARCHAR2(32767), c2 NUMBER);
TYPE t_rcv_tab IS TABLE OF t_rcv_row;
END;
CREATE OR REPLACE FUNCTION receive_message(
pipename IN VARCHAR2,
rcv_count IN NUMBER DEFAULT 1,
cache_func IN VARCHAR2 DEFAULT NULL)
RETURN msg_types.t_rcv_tab pipelined
AS
l_msg VARCHAR2(32767);
l_status NUMBER;
BEGIN
FOR i IN 1..rcv_count LOOP
l_status := DBMS_PIPE.RECEIVE_MESSAGE(
pipename => pipename,
cache_func => cache_func,
timeout => 1);
IF l_status != 0 THEN
raise_application_error(-20000,
'Message not received for attempt: ' || to_char(i) || ' status: ' ||
l_status);
END IF;
DBMS_PIPE.UNPACK_MESSAGE(l_msg);
pipe row(msg_types.t_rcv_row(l_msg));
END LOOP;
RETURN;
END;