DBMS_PIPE 程序包(持久性消息传送管道)
DBMS_PIPE
软件包允许同一实例中的两个或多个会话进行通信。
Oracle Autonomous Database on Dedicated Exadata Infrastructure 支持 Oracle Database 19c 中提供的核心 DBMS_PIPE
功能以及扩展。
See DBMS_PIPE in Oracle Database 19c PL/SQL Packages and Types Reference or Oracle Database 23ai PL/SQL Packages and Types Reference for details about the core DBMS_PIPE
functionality provided in Oracle Database.
DBMS_PIPE 持久性消息传送管道概览
管道功能具有多个潜在应用:外部服务接口、调试、独立事务处理和警报。
在 Autonomous Database 上,DBMS_PIPE 程序包扩展了支持持久性消息传递管道的功能。有关更多信息,请参见 Oracle Database 19c PL/SQL Packages and Types Reference 或 Oracle Database 23ai PL/SQL Packages and Types Reference 中的 DBMS_PIPE 。
DBMS_PIPE
中的持久消息:
-
支持发送和检索非常大的消息。
-
支持大量管道消息。
-
支持在单个数据库中、跨多个数据库以及跨不同区域的数据库共享消息。
-
支持使用同一云对象存储位置 URI 的多个管道。
持久性消息传递功能允许两个或多个数据库会话与存储在云对象存储中的消息进行通信。在管道中使用此功能消息可以仅对当前数据库可用,也可以对同一区域或跨不同区域的多个数据库可用。
持久性消息传送管道可以是任何支持的
DBMS_PIPE
类型之一:- 隐式管道:使用
DBMS_PIPE.SEND_MESSAGE
函数使用未知的管道名称发送消息时自动创建。 - 显式管道:使用具有用户指定的管道名称的
DBMS_PIPE.CREATE_PIPE
函数创建。 - 公共管道:任何对
DBMS_PIPE
软件包具有EXECUTE
权限的用户均可访问。 - 专用管道:由与管道创建者具有相同用户的会话访问。
- 隐式管道:使用
注意:
当使用持久性消息跨不同数据库发送和接收消息时,Oracle 建议您在发送或接收消息之前致电DBMS_PIPE.CREATE_PIPE
。使用 DBMS_PIPE.CREATE_PIPE
创建显式管道可确保使用所需的访问权限(公共或专用)创建管道(通过将 PRIVATE
参数设置为 FALSE
或使用默认值 TRUE
)。
DBMS_PIPE 限制
DBMS_PIPE
软件包不支持在使用不同字符集的数据库之间发送消息。例如,如果有一个使用 AL32UTF8 的 Autonomous Database 实例和一个使用 WE8MSWIN1252 的实例,则不能在这两个数据库之间发送带有 DBMS_PIPE
的消息。在这种情况下,如果尝试在这两个数据库之间发送带有 DBMS_PIPE
的消息,系统将引发错误 ORA-12704
。
持久性消息传送的 DBMS_PIPE 子程序概要
此表列出了 DBMS_PIPE
子程序并简要介绍了它们。
表 - DBMS_PIPE 程序包子程序
子程序 | 说明 |
---|---|
创建管道(专用管道必需)。 |
|
返回全局 |
|
返回用作默认位置 URI 的全局 |
|
NEXT_ITEM_TYPE 函数
|
返回缓冲区中下一项的数据类型。 |
在本地缓冲区中构建消息。 |
|
将来自命名管道的消息复制到本地缓冲区中。 |
|
清除本地缓冲区的内容。 |
|
删除指定的管道。 |
|
在命名管道上发送消息:如果命名管道不存在,这将隐式创建公共管道。 |
|
设置用作存储在云对象存储中的消息的默认身份证明的 |
|
设置用作云对象存储中存储的消息的默认位置 URI 的全局 |
|
UNIQUE_SESSION_NAME 函数
|
返回唯一的会话名。 |
UNPACK_MESSAGE 过程
|
访问缓冲区中的下一项。 |
CREATE_PIPE 函数
此函数显式创建公共或专用管道。如果 private
标志为 TRUE
,则将管道创建者指定为专用管道的所有者。
只能通过调用 REMOVE_PIPE
或关闭实例来删除显式创建的管道。
语法
DBMS_PIPE.CREATE_PIPE ( pipename IN VARCHAR2, maxpipesize IN INTEGER DEFAULT 66536, private IN BOOLEAN DEFAULT TRUE) RETURN INTEGER;
参数
表 - CREATE_PIPE 函数参数
Parameter (参数) | 说明 |
---|---|
|
要创建的管道的名称。 调用 注意:不要使用以 |
|
管道允许的最大大小(字节)。 管道上所有消息的总大小不能超过此数量。如果消息超过此最大值,则会阻止该消息。 缺省 管道的 缺省的 |
|
使用缺省值 调用 |
返回值
表 - CREATE_PIPE 函数返回值
返回 | 说明 |
---|---|
|
成功。 如果管道已存在,并且尝试创建管道的用户有权使用该管道,则 Oracle 将返回 0(表示成功),并且管道中已存在任何数据。 |
|
因命名冲突而失败。 如果存在具有相同名称且由其他用户创建的管道,则 Oracle 会发出错误 |
异常错误
表 - CREATE_PIPE 函数异常错误
例外 | 说明 |
---|---|
|
权限错误:同名的管道已存在,不允许您使用它。 |
范例
创建名为 MY_PIPE1
的显式专用
DECLARE
l_status INTEGER;
BEGIN
l_status := DBMS_PIPE.create_pipe(
pipename => 'MY_PIPE1',
private => TRUE);
END;
/
GET_CREDENTIAL_NAME 函数
此函数返回全局 credential_name
变量值,以便在将消息存储到云对象存储时使用。
语法
DBMS_PIPE.GET_CREDENTIAL_NAME RETURN VARCHAR2;
返回值
返回值 | 说明 |
---|---|
|
用于访问云对象存储的身份证明的名称。 |
范例
DECLARE
credential_name VARCHAR2(400)
BEGIN
credential_name := DBMS_PIPE.GET_CREDENTIAL_NAME;
END;
/
GET_LOCATION_URI 函数
此函数返回全局 location_uri
变量值,当管道消息存储到云对象存储时,该变量值可用作默认位置 URI。
语法
DBMS_PIPE.GET_LOCATION_URI RETURN VARCHAR2;
返回值
返回值 | 说明 |
---|---|
location_uri |
对象 URI。 |
范例
DECLARE
location_uri VARCHAR2(400)
BEGIN
location_uri := DBMS_PIPE.GET_LOCATION_URI;
END;
/
RECEIVE_MESSAGE 函数
此函数将消息复制到本地消息缓冲区中。
语法
DBMS_PIPE.RECEIVE_MESSAGE ( pipename IN VARCHAR2, timeout IN INTEGER DEFAULT maxwait, credential_name IN VARCHAR2 DEFAULT null, location_uri IN VARCHAR2) RETURN INTEGER;
参数
表 - RECEIVE_MESSAGE 函数参数
Parameter (参数) | 说明 |
---|---|
|
要接收消息的管道的名称。 以 |
|
等待消息的时间(秒)。超时为 0 可让您读取而不阻塞。 超时不包括运行使用 默认值:常量 |
|
用于存储消息的云存储的身份证明名称。
可以在调用 凭证对象必须具有运行 |
|
用于存储消息的云存储的位置 URI。
可以在调用 |
返回值
表 - RECEIVE_MESSAGE 函数返回值
返回 | 说明 |
---|---|
|
成功 |
|
超时。如果管道是隐式创建的且为空,则将其删除。 |
|
管道中的记录对于缓冲区来说太大。 |
|
已发生中断。 |
|
用户没有足够的权限从管道读取。 |
使用说明
-
要从管道接收消息,请先调用
RECEIVE_MESSAGE
。当您收到消息时,该消息将从管道中删除;因此,消息只能收到一次。对于隐式创建的管道,从管道中移除最后一个记录后,将删除管道。 -
如果您在调用
RECEIVE_MESSAGE
时指定的管道尚不存在,则 Oracle 会隐式创建管道并等待接收消息。如果消息未在指定的超时间隔内到达,则调用将返回并删除管道。 -
收到邮件后,必须对
UNPACK_MESSAGE
进行一次或多次呼叫才能访问邮件中的各个项目。UNPACK_MESSAGE
过程超载以解压缩DATE
、NUMBER
、VARCHAR2
类型的项目,还有两个额外的过程来解压缩RAW
和ROWID
项目。如果您不知道要解压缩的数据类型,请调用NEXT_ITEM_TYPE
来确定缓冲区中下一个项目的类型。 -
持久性消息保证只能由一个进程写入或读取。这样可以防止由于并发写入和读取而导致消息内容不一致。使用持久性消息传递管道时,
DBMS_PIPE
只允许执行一项操作,即发送消息或接收消息在给定时间处于活动状态。但是,如果由于正在进行的操作而无法执行某个操作,该进程将定期重试,直到达到timeout
值。 -
如果您使用 Oracle Cloud Infrastructure Object Storage 存储消息,则可以使用 Oracle Cloud Infrastructure 本机 URI 或 Swift URI。但是,位置 URI 和身份证明的类型必须匹配,如下所示:
-
如果使用本机 URI 格式访问 Oracle Cloud Infrastructure Object Storage ,则必须在身份证明对象中使用本机 Oracle Cloud Infrastructure 签名密钥验证。
-
如果使用 Swift URI 格式访问 Oracle Cloud Infrastructure Object Storage ,则必须在身份证明对象中使用验证令牌验证。
-
异常错误
表 - RECEIVE_MESSAGE 函数异常错误
例外 | 说明 |
---|---|
|
权限错误。权限不足,无法从管道中删除记录。管道由其他人拥有。 |
SEND_MESSAGE 函数
此函数在指定的管道上发送消息。
该消息包含在本地消息缓冲区中,其中填充了对 PACK_MESSAGE
的调用。可以使用 CREATE_PIPE
显式创建管道,否则将隐式创建管道。
语法
DBMS_PIPE.SEND_MESSAGE ( pipename IN VARCHAR2, timeout IN INTEGER DEFAULT MAXWAIT, credential_name IN VARCHAR2 DEFAULT null, location_uri IN VARCHAR2 ) RETURN INTEGER;
参数
表 - SEND_MESSAGE 函数参数
Parameter (参数) | 说明 |
---|---|
credential_name |
用于存储消息的云存储的身份证明名称。
可以在调用 凭证对象必须具有运行 |
location_uri |
用于存储消息的云存储的位置 URI。
可以在调用 |
|
管道允许的最大大小(字节)。 管道上所有消息的总大小不能超过此数量。如果消息超过此最大值,则会阻止该消息。默认值为 65536 字节。 管道的 如果将 缺省的 |
|
要放置消息的管道的名称。 如果使用的是显式管道,则这是在调用 注意:不要使用以 ' |
|
尝试在管道上放置消息时等待的时间(以秒为单位)。 默认值为常量 |
返回值
表 - SEND_MESSAGE 函数返回值
返回 | 说明 |
---|---|
|
成功。 如果管道已存在,并且尝试创建管道的用户有权使用该管道,则 Oracle 将返回 0(表示成功),并且管道中已存在任何数据。 如果以 |
|
超时。 此过程可能会超时,因为它无法锁定管道,或者因为管道仍然太满而无法使用。如果管道是隐式创建的且为空,则将其删除。 |
|
已发生中断。 如果管道是隐式创建的且为空,则将其删除。 |
|
权限不足。 如果存在具有相同名称且由其他用户创建的管道,则 Oracle 会发出错误 |
使用说明
-
持久性消息保证只能由一个进程写入或读取。这样可以防止由于并发写入和读取而导致消息内容不一致。使用持久性消息传递管道时,
DBMS_PIPE
只允许执行一项操作,即发送消息或接收消息在给定时间处于活动状态。但是,如果由于正在进行的操作而无法执行某个操作,该进程将定期重试,直到达到timeout
值。 -
如果您使用 Oracle Cloud Infrastructure Object Storage 存储消息,则可以使用 Oracle Cloud Infrastructure 本机 URI 或 Swift URI。但是,位置 URI 和身份证明的类型必须匹配,如下所示:
-
如果使用本机 URI 格式访问 Oracle Cloud Infrastructure Object Storage ,则必须在身份证明对象中使用本机 Oracle Cloud Infrastructure 签名密钥验证。
-
如果使用 Swift URI 格式访问 Oracle Cloud Infrastructure Object Storage ,则必须在身份证明对象中使用验证令牌验证。
-
异常错误
表 - SEND_MESSAGE 函数异常错误
例外 | 说明 |
---|---|
|
权限错误。权限不足,无法写入管道。管道是私有的,由其他人拥有。 |
SET_CREDENTIAL_NAME 过程
此过程设置在云对象存储中存储管道消息时用作默认身份证明的 credential_name
变量。
语法
DBMS_PIPE.SET_CREDENTIAL_NAME ( credential_name IN VARCHAR2 );
参数
Parameter (参数) | 说明 |
---|---|
|
用于访问云对象存储的身份证明的名称。 |
使用说明
如果您使用 Oracle Cloud Infrastructure Object Storage 存储消息,则可以使用 Oracle Cloud Infrastructure 本机 URI 或 Swift URI。但是,位置 URI 和身份证明的类型必须匹配,如下所示:
-
如果使用本机 URI 格式访问 Oracle Cloud Infrastructure Object Storage ,则必须在身份证明对象中使用本机 Oracle Cloud Infrastructure 签名密钥验证。
-
如果使用 Swift URI 格式访问 Oracle Cloud Infrastructure Object Storage ,则必须在身份证明对象中使用验证令牌验证。
范例
BEGIN
DBMS_PIPE.SET_CREDENTIAL_NAME(
credential_name => 'my_cred1');
END;
/
SET_LOCATION_URI 过程
此过程设置全局 location_uri
变量。
语法
DBMS_PIPE.SET_LOCATION_URI ( location_uri IN VARCHAR2 );
Parameter (参数)
Parameter (参数) | 说明 |
---|---|
location_uri |
对象或文件 URI。URI 的格式取决于您使用的云对象存储服务,有关详细信息,请参见云对象存储 URI 格式。 |
使用说明
如果您使用 Oracle Cloud Infrastructure Object Storage 存储消息,则可以使用 Oracle Cloud Infrastructure 本机 URI 或 Swift URI。但是,位置 URI 和身份证明的类型必须匹配,如下所示:
-
如果使用本机 URI 格式访问 Oracle Cloud Infrastructure Object Storage ,则必须在身份证明对象中使用本机 Oracle Cloud Infrastructure 签名密钥验证。
-
如果使用 Swift URI 格式访问 Oracle Cloud Infrastructure Object Storage ,则必须在身份证明对象中使用验证令牌验证。
范例
BEGIN
DBMS_PIPE.GET_LOCATION_URI(
location_uri => 'https://objectstorage.us-phoenix-1.oraclecloud.com/n/namespace-string/b/bucketname1/');
END;
/