我在 Oracle SQL Server 中遇到了全局临时表的概念。根据 tutorial on global temporary tables :
The data in a global temporary table is private, such that data inserted by a session can only be accessed by that session.
我相信这可以允许以下场景:客户端启动存储过程两次,每次都预先填充全局临时表以供 sp 处理。这两个计算不会相互干扰,因为每个计算只看到自己的数据,而不是共享数据,就像普通表的情况一样。
但是,这完全取决于 session 的构成以及 session 的开始和结束时间。
根据Oracle Database Concepts Glossary :
Session: A logical entity in the database instance memory that represents the state of a current user login to a database. A single connection can have 0, 1, or more sessions established on it.
Connection: Communication pathway between a client process and an Oracle database instance.
这并没有消除我所有的困惑,所以这是我的具体问题:
我的应用程序在其整个生命周期内都保持与 Oracle SQL 服务器的单一连接。它在同一个连接上连续执行多个 SQL 命令/查询,这些查询中的每一个都是自己的 session ,它们会共享一个 session ,还是不是简单的回答?
考虑这个伪代码:
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);
}
我已经在我的应用程序中运行了上面的命令,正如预期的那样,命令
c2
返回零结果。我认为这意味着每个查询都构成了自己的 session ,这就是我正在寻找的。但我可以依赖吗?
最佳答案
What is the lifecycle of a Oracle SQL session?
session 是一个逻辑实体,从应用程序代码连接到数据库到断开连接一直存在。
session 独立于支持它们的物理(基于资源的)实体,例如连接、服务器进程、网络连接等。
在最简单(也是最常见的 imo)配置(即“专用服务器”)中,逻辑 session 与物理连接和服务器进程之间存在 1-1 关系。在支持大量用户的更高级配置中,物理资源(连接、进程、网络资源)可以由多个 session 共享/复用。
I have run the above in my application, and as expected, the command c2 returned zero results. I take this to mean that each query constitutes its own session
除非您的应用程序代码在调用之间断开或关闭/释放其连接,否则这几乎肯定是 不是 案子。
可以使用两个选项创建全局临时表:
ON COMMIT DELETE ROWS
和 ON COMMIT PRESERVE ROWS
.第一个将导致在
commit
上删除所有 GTT 数据。或 rollback
.第二个将导致所有 GTT 数据在整个 session 中保持不变。如果您不使用
ON COMMIT DELETE ROWS
,那么您不应假设 GTT 在给定调用开始时为空。如果您要求在 a 程序开始时 GTT 为空,您必须 DELETE FROM
您在程序开始时(或最后)的 GTT(或 TRUNCATE
it)。请注意,即使有此限制(即,必须在 session 中自己处理清空 GTT),全局临时表仍然很有用,因为它们仍然可以保护一个 session 免受另一个 session 的数据的影响。与常规表相比,它们还编写更少的重做,尤其是在 12.1 及更高版本中。事实上,从 Oracle 12.1 开始,它们根本不需要编写任何重做,这使得它们在只读和备用数据库中非常有用。
在旁边...
I have run the above in my application, and as expected, the command c2 returned zero results
为此,您的 GTT 必须是使用
ON COMMIT DELETE ROWS
创建的。并且您的应用程序代码启用了某种“自动提交”功能,它会在每个 Command.Execute()
之后自动提交。 .否则你会误解/误报你的测试结果。
关于sql - Oracle SQL session 的生命周期是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59411723/