Oracle
 sql >> база данни >  >> RDS >> Oracle

мога ли да поддържам една сесия на Oracle от два oci клиента?

Ако използвате 11g база данни, можете да използвате DBMS_XA пакет за да позволи на една сесия да се присъедини към транзакция, започната от първата сесия. Както демонстрира Тим Хол, можете да стартирате транзакция в една сесия, да се присъедините към тази транзакция от друга сесия и да прочетете неизвършените промени, направени в транзакцията. За съжаление обаче това няма да помогне с променливите на сесията (ако приемем, че „променлива на сесията“ означава променлива на пакета, която има обхват на сесията).

Създайте пакета и таблицата:

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 започваме глобална транзакция, задаваме променливата на пакета и вмъкваме ред в таблицата, преди да спрем глобалната транзакция (което позволява на друга сесия да я възобнови)

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 задайте стойността на контекстната променлива G_VAR до 47 за сесия 12345

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



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Entity Framework Oracle и Sql Server - как да изградите приложение, независимо от база данни

  2. Можем ли да преразпределим Oracle tools.jar?

  3. Как да получите първите два знака от низ в заявка за оракул?

  4. Изберете само колони без стойности Null в Oracle

  5. Низ за заявка на Oracle, включително знак за тире