Oracle – Concorrência Simplificada

Hoje a matéria é muito simples, é mais uma clarificação “Back to Basics” do que um post elaborado com investigação.
Serve assim de material de base para quando surgirem mais dúvidas deste tipo no meu local de trabalho 😉

A ideia é simples: Aplicar um select _durante_ o update e garantir que existe total consistência de leitura
e que não existe qualquer “bloqueio” em nenhuma sessão dada a arquitectura. Depois do exemplo prático, explicarei como funciona.

SQL> create table t2_locks as select rownum N1, dbms_random.string('A', 10) S1 from dual connect by level <= 1000000;

Table created.


SQL> select sid from v$session where audsid=userenv('SESSIONID');

SID
----------
42


SQL> select sid from v$session where audsid=userenv('SESSIONID');

SID
----------
32

Validações na SID 42:

 

SQL> select MIN(N1) from t2_locks;

MIN(N1)
----------
1


SQL> select MAX(N1) from t2_locks;

MAX(N1)
----------
1000000


SQL> select avg(N1) from t2_locks;

AVG(N1)
----------
500000.5

Estas três validações irão permitir verificar a consistência dos dados durante o update e após o update (sem COMMIT).

Avançaremos então com o update demorado à SID 42, enquanto na SID 32 faremos as validações enquando decorre o update.
Para facilitar a compreensão, farei um pequeno video (desta vez sem som ;)):

O update será o seguinte:

 

 

update t2_locks set N1 = (select MIN(dbms_random.value(0,40000)) from dual connect by level <= 2000000);


Como puderam ver no vídeo e apesar de não ter mostrado os locks feitos na v$lock durante o processo todo, não existe qualquer interferência das sessões entre elas, pois o Oracle possui um mecanismo de consistência de leitura que faz com que o resultado da query venha apenas de um ponto no tempo (na altura que a query começa) para uma ou mais transacções. Quando acontece o update (ou qualquer DML), o Oracle usa os rollback segments para providenciar dados consistentes, ou seja, os rollback segments contem os valores antigos dos dados que vão sendo sujeitos ao update (ou qualquer DML). O select poderá ler parte dos dados do table segment (da tabela em si) e outra parte dos rollback segment enquanto decorre o update ou este não está “commited”. É basicamente um snapshot dos data blocks antes da sua modificação. Assim que é feito o commit e executado um select, os data blocks presentes no rollback segments são descartados e os dados do select virão exclusivamente do table segment (ou index segment, se for o caso).

É este rollback segment que permite que aquando de um rollback exista o processo de reversão dos dados sujeitos ao DML.
Explica também porque é que um rollback em média demora o mesmo tempo que a própria operação de DML que o originou, ou seja,
o Oracle tem que ir ao rollback segment lê-lo e repor tudo como estava, ou seja, a operação inversa aquando do DML a nível de
segments.

 

PS: Acabei por fazer metade em texto, metade em vídeo 🙂

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s