Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/150.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 我可以从两个oci客户端维护一个Oracle会话吗?_C++_Oracle_Oracle Call Interface - Fatal编程技术网

C++ 我可以从两个oci客户端维护一个Oracle会话吗?

C++ 我可以从两个oci客户端维护一个Oracle会话吗?,c++,oracle,oracle-call-interface,C++,Oracle,Oracle Call Interface,是否可以从一个进程通过OCI连接到Oracle,然后从另一个进程连接到同一数据库会话 在我当前的应用程序中,有两种访问数据库的方法:一种是同步的,另一种是异步的,使用单独的进程,通过套接字进行通信。 问题是这两种方法实现不同的会话 如果我尝试(例如)在一个会话上进行更新,然后尝试在不提交的情况下从另一个会话更新同一个表,则OCI调用将挂起 更糟糕的是,如果会话变量是从一个会话设置的,而另一个会话没有看到它,这正是名称所说的….如果您使用的是11g数据库,则可以使用允许一个会话加入由第一个会话启动

是否可以从一个进程通过OCI连接到Oracle,然后从另一个进程连接到同一数据库会话

在我当前的应用程序中,有两种访问数据库的方法:一种是同步的,另一种是异步的,使用单独的进程,通过套接字进行通信。 问题是这两种方法实现不同的会话

如果我尝试(例如)在一个会话上进行更新,然后尝试在不提交的情况下从另一个会话更新同一个表,则OCI调用将挂起


更糟糕的是,如果会话变量是从一个会话设置的,而另一个会话没有看到它,这正是名称所说的….

如果您使用的是11g数据库,则可以使用允许一个会话加入由第一个会话启动的事务。正如Tim Hall演示的,您可以在一个会话中启动事务,从另一个会话加入该事务,并读取事务中未提交的更改。然而,不幸的是,假设会话变量意味着具有会话作用域的包变量,这对会话变量没有帮助

创建包和表:

CREATE TABLE foo( col1 NUMBER );

create or replace package pkg_foo
as
  g_var number;
  procedure set_var( p_in number );
end;

create or replace package body pkg_foo
as
  procedure set_var( p_in number )
  as
  begin
    g_var := p_in;
  end;
end;
在会话1中,我们启动一个全局事务,设置package变量,并在挂起全局事务之前在表中插入一行,这允许另一个会话恢复它

SQL> ed
Wrote file afiedt.buf

  1  declare
  2    l_xid dbms_xa_xid := dbms_xa_xid( 1 );
  3    l_ret integer;
  4  begin
  5    l_ret := dbms_xa.xa_start( l_xid, dbms_xa.tmnoflags );
  6    pkg_foo.set_var(42);
  7    dbms_output.put_line( 'Set pkg_foo.g_var to ' || pkg_foo.g_var );
  8    insert into foo values( 42 );
  9    l_ret := dbms_xa.xa_end( l_xid, dbms_xa.tmsuspend );
 10* end;
SQL> /
Set pkg_foo.g_var to 42

PL/SQL procedure successfully completed.
在会话2中,我们恢复全局事务,从表中读取,读取会话变量,然后结束全局事务。请注意,对表的查询可以看到我们插入的行,但包变量的更改不可见

SQL> ed
Wrote file afiedt.buf

  1  declare
  2    l_xid dbms_xa_xid := dbms_xa_xid( 1 );
  3    l_ret integer;
  4    l_col1 integer;
  5  begin
  6    l_ret := dbms_xa.xa_start( l_xid, dbms_xa.tmresume );
  7    dbms_output.put_line( 'Read pkg_foo.g_var as ' || pkg_foo.g_var );
  8    select col1 into l_col1 from foo;
  9    dbms_output.put_line( 'Read COL1 from FOO as ' || l_col1 );
 10    l_ret := dbms_xa.xa_end( l_xid, dbms_xa.tmsuccess );
 11* end;
SQL> /
Read pkg_foo.g_var as
Read COL1 from FOO as 42

PL/SQL procedure successfully completed.
要在会话之间共享会话状态,是否可以使用包变量而不是包变量?如果希望同时读取数据库表和会话状态,可以将其与DBMS_XA包结合使用

使用getter和setter创建上下文和包

CREATE CONTEXT my_context
  USING pkg_foo
  ACCESSED GLOBALLY;

create or replace package pkg_foo
as
  procedure set_var( p_session_id in number,
                     p_in         in number );
  function get_var( p_session_id in number )
    return number;
end;

create or replace package body pkg_foo
as
  procedure set_var( p_session_id in number,
                     p_in         in number )
  as
  begin
    dbms_session.set_identifier( p_session_id );
    dbms_session.set_context( 'MY_CONTEXT', 'G_VAR', p_in, null, p_session_id );
  end;
  function get_var( p_session_id in number )
    return number
  is
  begin
    dbms_session.set_identifier( p_session_id );
    return sys_context('MY_CONTEXT', 'G_VAR');
  end;
end;
在会话1中,将会话12345的上下文变量G_VAR的值设置为47

begin
  pkg_foo.set_var( 12345, 47 );
end;
现在,会话2可以从上下文中读取值

  1* select pkg_foo.get_var( 12345 ) from dual
SQL> /

PKG_FOO.GET_VAR(12345)
----------------------
                    47

是的,会话变量是指具有会话作用域的包变量…所以这种方法不是解决方案。无论如何谢谢你@user581243-您是否有可能使用全局上下文而不是包变量?我用这种可能性更新了我的答案。再次感谢。这很有趣。但是,我需要在C++代码层解决这个问题,而不是在PL/SQL代码层。这不是一次性的情况,而是经常发生的事情。对于我们的应用程序,C++代码比PL/SQL代码要少得多,这就是为什么我不想把复杂度转换到PL/SQL代码的原因。在每个会话都用不同的用户名连接时,有没有一种方法使BMSMyxA工作?