Oracle 11g - 通过 user_id 跨池连接共享 Sys_Context 值

Posted

技术标签:

【中文标题】Oracle 11g - 通过 user_id 跨池连接共享 Sys_Context 值【英文标题】:Oracle 11g - Share Sys_Context values across pool connection by user_id 【发布时间】:2018-11-05 18:46:18 【问题描述】:

任何人都可以提供一个足够好的共享Sys_Context 使用示例

Dbms_Session.Set_Identifier(user_id)

我希望在用户成功登录后能够从不同的连接访问某些 sys 上下文属性。


我的场景

Spring Boot 2.0.6 使用 HikariCP 连接池连接到 Oralce 11g

程序

    用户访问登录页面 登录 -> user_id 设置为 Dbms_Session.Set_Context('ENV', USER_ID, user_id) 用户访问某些资源(例如帐户)-> Sys_Context('ENV', user_id) 返回 Null

Sys_Context('ENV', user_id) 返回 Null,因为资源通过不同的连接访问 db,因此 CURRENT 上下文中没有 user_id。


此 Oracle 文档声称这是可能的:https://docs.oracle.com/cd/B28359_01/network.111/b28531/app_context.htm#DBSEG79745

如下所示: https://oracle-base.com/articles/misc/dbms_session https://web.stanford.edu/dept/itss/docs/oracle/10gR2/network.102/b14266/apdvcntx.htm

如果这不可能,请说明 Dbms_Session.Set_Identifier(user_id) 的确切用途,因为我发现这些文档非常晦涩,我无法复制它们显示的任何示例。

【问题讨论】:

【参考方案1】:

    必须使用GLOBALLY ACCESSIBLE 选项创建上下文,例如

    create context ENV using scott.security_pkg accessed globally;
    

    dbms_session.set_context 使用会话 ID(在 scott.security_pkg 内)调用,例如

    dbms_session.set_context(
      namespace => 'ENV',
      attribute => 'user_id',
      value     => 'jane',
      client_id => '12345');
    

    dbms_session.set_identifier 必须在每个会话中使用用户的会话 ID 调用,例如

    dbms_session.set_identifier(client_id=>'12345');
    

    现在,您可以使用sys_context 获取属性的值,例如

    sys_context('ENV','user_id')
    

这只是一个使用user_id 作为您希望存储的属性名称的示例。重要的一点是client_id,它唯一标识用户的会话。

【讨论】:

谢谢,关键是创建一个 GLOBALLY ACCESSIBLE 上下文并在每个 datasource.getConnection() 之前调用 dbms_session.set_identifier(AOP 或手动)。我已经使用 2 个 PLSQL Developer (IDEA) 连接进行了测试。上下文确实可以从不同的会话中访问并显示在select * from global_context

以上是关于Oracle 11g - 通过 user_id 跨池连接共享 Sys_Context 值的主要内容,如果未能解决你的问题,请参考以下文章

Oracle11g——Oracle 简介

oracle11g windows迁移至linux

通过 java 从网络机器连接到 Oracle 11g 失败

oracle 11g 程序连接不上,PlSql通过配置选项后能连上

『ORACLE』Oracle GoldenGate搭建(11g)

应用程序升级到oracle 11g后,无法通过SOAP API Web服务检索数据