wal*_*pus 6 sql oracle oracle12c
我在 Oracle SQL Server 中遇到了全局临时表的概念。根据关于全局临时表的教程:
全局临时表中的数据是私有的,因此会话插入的数据只能由该会话访问。
我相信这可以允许以下场景:客户端启动存储过程两次,每次都预先填充全局临时表以供 sp 处理。这两个计算不会相互干扰,因为每个计算只看到自己的数据,而不是共享数据,就像普通表的情况一样。
但是,这完全取决于会话的构成以及会话的开始和结束时间。
会话:数据库实例内存中的逻辑实体,表示当前用户登录数据库的状态。单个连接上可以建立 0、1 或多个会话。
连接:客户端进程和 Oracle 数据库实例之间的通信路径。
这并没有消除我所有的困惑,所以这是我的具体问题:
我的应用程序在其整个生命周期内都保持与 Oracle SQL 服务器的单一连接。它在同一个连接上连续执行多个 SQL 命令/查询,这些查询中的每一个都是它自己的会话,它们会共享一个会话,还是不是简单的回答?
考虑这个伪代码:
Command c1 = new Command("insert into TMP_TABLE (FOO) values ('TEST')");
Command c2 = new Command("select FOO from TMP_TABLE");
c1.Execute();
foreach (var value in c2.Query().Select("FOO"))
{
print(value);
}
Run Code Online (Sandbox Code Playgroud)
我已经在我的应用程序中运行了上面的代码,正如预期的那样,该命令c2返回了零结果。我认为这意味着每个查询都构成了自己的会话,这就是我正在寻找的。但我可以依赖吗?
Oracle SQL 会话的生命周期是怎样的?
会话是一个逻辑实体,从应用程序代码连接到数据库到断开连接为止一直存在。
会话独立于支持它们的物理(基于资源的)实体,例如连接、服务器进程、网络连接等。
在最简单(也是最常见的,imo)配置(即“专用服务器”)中,逻辑会话与物理连接和服务器进程之间存在 1-1 关系。在支持大量用户的更高级配置中,物理资源(连接、进程、网络资源)可以由多个会话共享/复用。
我已在我的应用程序中运行上述命令,并且正如预期的那样,命令 c2 返回零结果。我认为这意味着每个查询都构成自己的会话
除非您的应用程序代码在调用之间断开连接或关闭/释放其连接,否则几乎肯定不是这种情况。
可以使用两个选项创建全局临时表:ON COMMIT DELETE ROWS和ON COMMIT PRESERVE ROWS。
第一个将导致所有 GTT 数据在commit或 时被删除rollback。第二个将导致所有 GTT 数据在整个会话中持续存在。
如果您不使用ON COMMIT DELETE ROWS,那么您不应假设GTT 在给定调用开始时为空。如果您要求 GTT 在过程开始时为空,则必须将DELETE FROMGTT(或TRUNCATE它)放在过程的开始(或最后)。
请注意,即使有此限制(即,必须在会话中自己处理清空 GTT),全局临时表仍然有用,因为它们仍然可以保护一个会话不查看另一个会话的数据。它们还比常规表写入更少的重做,尤其是在 12.1 及更高版本中。事实上,从 Oracle 12.1 开始,它们根本不需要写入任何重做,这使得它们在只读和备用数据库中非常有用。
我已在我的应用程序中运行上述内容,正如预期的那样,命令 c2 返回零结果
为了使这一点有意义,您的 GTT 必须是使用创建的,ON COMMIT DELETE ROWS并且您的应用程序代码启用了某种“自动提交”功能,在每个Command.Execute(). 否则你就会误解/误报你的测试结果。
| 归档时间: |
|
| 查看次数: |
1112 次 |
| 最近记录: |