sql >> Database teknologi >  >> RDS >> Oracle

kan jeg vedligeholde én Oracle-session fra to oci-klienter?

Hvis du bruger en 11g-database, kan du bruge DBMS_XA pakke for at tillade en session at deltage i en transaktion startet af den første session. Som Tim Hall demonstrerer, kan du starte en transaktion i én session, deltage i den transaktion fra en anden session og læse de uforpligtede ændringer i transaktionen. Desværre vil det dog ikke hjælpe med sessionsvariabler (forudsat at "sessionsvariabel" betyder pakkevariabel, der har sessionsomfang).

Opret pakken og tabellen:

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;

I session 1 starter vi en global transaktion, indstiller pakkevariablen og indsætter en række i tabellen, før vi suspenderer den globale transaktion (hvilket tillader en anden session at genoptage den)

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.

I session 2 genoptager vi den globale transaktion, læser fra tabellen, læser sessionsvariablen og afslutter den globale transaktion. Bemærk, at forespørgslen mod tabellen ser den række, vi indsatte, men ændringen af ​​pakkevariabelen er ikke synlig.

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.

For at dele sessionstilstand mellem sessionerne, ville det være muligt at bruge en global applikationskontekst i stedet for at bruge pakkevariabler? Du kan kombinere det med DBMS_XA pakker, hvis du vil læse både databasetabeller og sessionstilstand.

Opret konteksten og pakken med getter og 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;

I session 1 skal du indstille værdien af ​​kontekstvariablen G_VAR til 47 for session 12345

begin
  pkg_foo.set_var( 12345, 47 );
end;

Nu kan session 2 læse værdien fra konteksten

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

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



  1. Kan en oracle SQL-forespørgsel udføre en strengforespørgsel valgt fra en tabel?

  2. Kopiering af CSV til Amazon RDS-hostet Postgresql-database

  3. Transponer rækker og kolonner uden aggregat

  4. SqlConnection.Close() inde ved hjælp af sætning