简单讲,同一个session下pageckage中的全局变量时公共的,会导致冲突。
以下是一些相关的资料和文章。
1
前言 在程序实现过程中,经常用遇到一些全局变量或常数。在程序开发过程中,往往会将该变量或常数存储于临时表或前台程序的全局变量中,由此带来运行效率降低<频繁读取临时表>或安全隐患<存于前台程序变量,可跟踪内存变量获得>。
本文主要论述将全局变量或常数存取程序包的优点和实现方法。 2 优点 2.1
执行效率比存储于临时表高,不需要频率存取临时表 2.2 将全局变量藏于最后防线<数据库>,安全性较高 2.3
在视图中可以调用程序包的变量,实现动态视图 3 实现 3.1 实现方法概述
Oracle数据库程序包中的变量,在本程序包中可以直接引用,但是在程序包之外,则不可以直接引用。对程序包变量的存取,可以为每个变量配套相应的存储过程<用于存储数据>和函数<用于读取数据>来实现。
Oracle存储过程中的面向对象特性
1.
package的封装 Package提供了一种封装的机制,可以将存储过程、方法、定值、Type放在一起。这实际上应该是一种面向对象的思想。pck文件包括两部分:package
和package body。package中声明了可用的过程、方法,package
body隐藏了实现的细节。 通过如上,我们即可以将位于数据库中的表记录数据看成是一个对象,而通过操作存储过程,实现对其的访问、修改。
2.
package内部,type的使用 type实际上就像class或容器一样。你可以在package内部自主定义type,并非常方便地使用它们。如: type
my_cares is record( a number, b number, c number, d
varchar2(10) ); 定义好后,如要使用可以先声明再直接调用。 declare the_care my_cares; i
number := 0; begin the_care.a := 1; the_care.b := 2; i :=
the_care.b; dbms_output.put_line(‘value is ’ ||
the_care.d); end; 在procedure之间传递参数时,通过传递type
类型的参数,对程序的结构、今后的调整维护,都非常方便。
3.
package内的参数传递 我们可以在package内定义各式各样的类型,而且它们可以作为公共参数,当在存储过程之间传递时带来便捷,就像2中所述那样。更为主要的是,package允许定义“属性”变量,格式如: <VariableName>
<Datatype>; 这类似Java语法,并且通过在package或package
body中声明,可以分别作为public和private的属性变量来使用!这些变量可以在package body begin后被初始化,并被package
body中不同的存储过程、方法调用。
4.
其他资料 不同session执行package又是什么情况呢?这里只引用一下相关的资料。由于package的全局变量在数据库层次上并不可见,所以每个session都可以认为是一个被实例化了的package对象。在session级别上对全局变量执行的赋值操作并不会被其他session看到,很好地体现了数据的封装性。 而由于oracle的package并没有显式地创建实例,所以package的全局变量跟其他面向对象语言的类的属性还是有区别的。最显著的区别在于这里的全局变量不能作为属性值在其他procedure或者function中进行调用。如果希望达到这样的效果,可以通过在package中定义function来实现。这些function的写法,有些像Java中的getter
和 setter。
什么是session
俗来讲,session
是通信双方从开始通信到通信结束期间的一个上下文(context)。 这个上下文是一段位于服务器端的内存:记录了本次连接的客户端机器,
通过那个应用程序,那个用户在登录等信息。 session
是和connection同时建立的,两者是对同一件事情不同层次的描述。简单讲,connection是物理上的客户机同服务器段的通信链路,session是逻辑上的用户同服务器的通信交互。 oracle中一个用户登录oracle服务器的前提,就是该用户具有oracle的
“create
session”权限。oracle允许同一个用户在同一个客户机上建立多个同服务器的连接,这一点从oracle的视图V$session中可以看到。每个session都代表了用户与服务器的一个交互。就像两个国家之间可以同时开展很多谈判,经济的,环境的等等。关闭了有关经济的谈判,不会影响到环境谈判的进行。后台进程PMON会每隔一段时间,就会测试用户连接状况,如果连接已断开,PMON会清理现场,释放相关的资源。 在具体的应用场景中connction
和 session 有很多情况: 1. sqlplus 登录
oracle 这种场景比较容易理解,一个连接对应一个session。 2. 其他客户端工具登录oracle 比如:pl/sql
developer 登录oracle。pl/sql developer 可以设置是否每个窗口共用同一个session.
如果想在调试窗口调试存储过程或函数,则必须设置为共享session。 如果设置为非共享, 则每次打开一个操作窗口,pl/sql developer
会利用最初输入的帐户和口令建立新的connection 和 session. 3. IIS
用程序登录oracle 这种情况下,其实是IIS在登录oracle。connection 和 session
的建立情况和iis机制相关。(以下是参考了网友的观点,文章来源:http://www.cnblogs.com/) “对于Oracle来说,安全的Sessions数应该为Sessions
= (IIS process number) * (min pool
size)。” IIS进程:在IIS6.0中,采用了新的进程隔离模式来响应用户的请求,在IIS管理器中,可以设置应用程序池的最大进程数。对于新的WEB应用请求,IIS进程管理器会启动多个W3wp.exe进行响应。 4、
其他情况 有待各路英雄补充 orcale的session内存 oracle
的连接分为两种:独占式,共享式。 在独占式连接情况下,session(如游标,排序去,sql区)是在PGA中分配的。 在共享式连接情况下,session的一部分(如UGA)是在中SGA的larg
pool中分配的。 oracle session 和process oracle中每个process 都有对应的session。
process 分为 用户进程在V$session 中可用条件:$session.type = 'USER'.查询。
后台进程在V$session 中可用条件:$session.type = 'BACKGROUND'查询。
常见的后台进程: SMON,PMON,DBWR,LGWR,MMAN,MRP,
RFS,RECO,CKPT,ARCH,Dnnn,Snnn,LMON,LMD0,QMNn,TRWR,WMON,LCKnnn,SNPnnn,
MMON,DMON,SNP session
相关的初始化参数: process:oracle的连接数(sessions)与其参数文件中的进程数(process)相关,它们的关系如下:sessions=(1.1*process+5),我们可以通过修改inia.ora的这个process参数在更改可连接的最大session数。 workarea_size_policy:PGA用手动管理还是自动管,
在AUTO的时候每个session最多能用到5%或100M.
如何跨不同session支持可读写的全局变量
oracle9i以上通过GLOBALLY ACCESSED
CONTEXT方式可以实现。但在11GR2之前,这个特性不能在RAC环境下使用,让我们稍微感到一些遗憾.
首先,用户必须有CREATE ANY CONTEXT权限.
为了隔离访问,我以包的方式说明如何声明\修改\获取全局变量.
---- 创建CONTEXT并和一个包绑定: Create or Replace Context AppContext using BasePkg
ACCESSED GLOBALLY
---- 创建一个包来写入变量: create or replace package BasePkg as procedure
SetAppContext( name in varchar2,value in varchar2 );
procedure init; end BasePkg; ----包体内容
create or replace package body BasePkg
as
G_SESSION_ID Constant Number := -1;
procedure init IS begin
NULL; end;
procedure SetAppContext( name in varchar2,value in varchar2 )
as begin dbms_session.setAppContext ( 'FMIS_BASE',
name, value, NULL, G_SESSION_ID ); end; begin
dbms_session.set_identifier( g_session_id ); end BasePkg ; --- 每次初始化以后
EXEC BasePkg .init;
--就可以跨session,访问全局变量了
select sys_context( 'FMIS_BASE' ,'变量名' ) from dual
|