【问题标题】:Oracle Stored Procedure benchmarkingOracle 存储过程基准测试
【发布时间】:2011-12-20 12:45:44
【问题描述】:

我是一名使用旧版 Oracle 数据库的 .Net Web 开发人员。过去我使用过 nHibernate 等 orm 工具,但这里的所有数据库通信都需要通过存储过程完成。我们的 dba 要求我们将一堆管理信息传递给我们调用的每个程序,包括最终用户的用户名/域/IP。然后,此数据用于调用另一个存储过程,该过程在每次调用过程时记录使用信息。

我不太精通 Oracle 或 Pl/Sql,我正试图以一种尽可能符合最佳实践的简洁方式编写我的 .Net 代码。在我看来,将额外数据传递给每个过程的过程在 .Net 和 Oracle 端都是混乱而乏味的。

有没有人知道在没有所有开销的情况下实现 dba 目标的更好方法?或者这是我应该习惯的标准做事方式。

【问题讨论】:

  • 这绝对不是标准的,而且绝对不是一个好方法。您需要传递什么样的“额外”数据(即用户名等)?
  • 是的,我们需要传递用户名、域、IP 地址。

标签: asp.net .net oracle stored-procedures


【解决方案1】:

我会使用上下文而不是向每个存储过程调用传递额外的参数。上下文是存储存储过程都可以引用的任意会话级状态数据的方便位置。

例如,我可以为我的应用程序创建一个上下文 MYAPP_CTX 并创建一个简单的包,让我可以在上下文中设置我想要的任何值。

SQL> create context myapp_ctx using ctx_pkg;

Context created.

SQL> create package ctx_pkg
  2  as
  3    procedure set_value( p_key in varchar2, p_value in varchar2 );
  4  end;
  5  /

Package created.

SQL> create package body ctx_pkg
  2  as
  3    procedure set_value( p_key in varchar2, p_value in varchar2 )
  4    as
  5    begin
  6      dbms_session.set_context( 'MYAPP_CTX', p_key, p_value );
  7    end;
  8  end;
  9  /

Package body created.

当应用程序从连接池中获得连接时,它会简单地设置所有上下文信息一次。

SQL> begin
  2    ctx_pkg.set_value( 'USERNAME', 'JCAVE' );
  3    ctx_pkg.set_value( 'IP_ADDRESS', '192.168.17.34' );
  4  end;
  5  /

PL/SQL procedure successfully completed.

同一会话中的后续调用和查询可以只询问存储在上下文中的任何值。

SQL> select sys_context( 'MYAPP_CTX', 'USERNAME' )
  2    from dual;

SYS_CONTEXT('MYAPP_CTX','USERNAME')
--------------------------------------------------------------------------------
JCAVE

实际上,您几乎肯定希望将clear_context 过程添加到调用dbms_session.clear_context( 'MYAPP_CTX' ) 的包中,以在将连接返回到连接池时清除上下文中设置的任何值,以避免无意中允许上下文来自一个会话的信息会渗透到另一个会话中。您可能还会使用单独的程序来设计包,以设置和获取至少公共密钥(用户名、IP 地址等),而不是在多个位置硬编码“用户名”。为了简单起见,我使用了一个通用的 set_value 方法。

【讨论】:

  • 我可能遗漏了一些东西,但如果多个用户同时访问会话,似乎可能存在潜在的并发问题。例如,如果第二个用户会话设置了用户名/IP,然后第一个用户会话调用一个请求用户名的存储过程,会发生什么情况。不会返回第二次会话设置的用户名吗?
  • @zaq - 上下文(默认情况下)在数据库会话中是本地的。一次只能有一个用户使用数据库会话(尽管多个中间层会话在从连接池中检索连接时可能会随着时间的推移共享一个数据库会话)。这就是为什么您通常会在连接返回到连接池时、从连接池中拉出连接时或同时清除上下文的原因。两个数据库会话将在各自的上下文中拥有单独的数据副本——一个会话不会看到另一个会话上下文中的信息。
猜你喜欢
  • 1970-01-01
  • 2011-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-15
  • 2011-01-03
  • 2011-12-29
相关资源
最近更新 更多