Consultor Eletrônico



Kbase 51815: Níveis de isolamento de transações no OpenEdge SQL
Autor   Tatiane Koslinsky - CAT
Acesso   Público
Publicação   03/02/2017
Uma transação é uma seqüência de operações executadas como uma única unidade lógica de trabalho. Para garantir um processamento de forma confiável e segura, as transações devem apresentar quatro propriedades, chamadas atomicidade, consistência, isolamento e durabilidade (propriedades ACID).

O isolamento é uma propriedade que garante que as transações concorrentes em um mesmo sistema não serão afetadas por atualizações realizadas em outras transações concorrentes. O OpenEdge SQL suporta quatro níveis de isolamento de transação (transaction isolation levels) diferentes, que oferencem diferentes graus de isolamento e concorrência:

READ UNCOMMITTED
READ COMMITTED
REPEATABLE READ
SERIALIZABLE

Como via de regra, quanto maior o nível de isolamento, menor a concorrência do sistema. Antes de analisarmos as características de cada nível de isolamento, precisamos entender quais problemas podem ocorrer quando duas ou mais transações executam simultaneamente em um sistema. Os exemplos apresentados são baseados em tabelas do banco de dados de demonstração sports.


Dirty Read

Dirty Read (ou leitura suja) ocorre quando uma transação A lê algum dado que está sendo alterado por outra transação B mas ainda não foi confirmado (commit). Caso a transação B que está modificando os dados aborte (rollback), a transação A leu dados que logicamente numca existiram. O exemplo a seguir ilustra este problema (a linha iniciada por -- indica um comentário):

-- usuário 1:
INSERT INTO PUB.state VALUES ('SP', 'São Paulo', 'South');

-- usuário 2, seleciona estados do Sul:
SELECT * FROM PUB.state WHERE Region = 'South';

-- usuário 1 lembrou que SP não é da região sul:
ROLLBACK;

-- usuário 2 leu "SP - São Paulo - South", que logicamente nunca existiu.


Non-repeatable read

Uma non-repeatable read ocorre quando uma transação lê um mesmo registro mais de uma vez e encontra valores diferentes para estes registros a cada leitura. Vejamos o exemplo:

-- usuário 1, retorna "AL - Alabama - South":
SELECT * FROM PUB.state WHERE Region = 'South';
-- usuário 2 atualiza nome do estado AL p/ Alagoas:

UPDATE PUB.state SET "State-Name" = 'Alagoas' WHERE State = 'AL';
COMMIT;

-- usuário 1, retorna "AL - Alagoas - South":
SELECT * FROM PUB.state WHERE Region = 'South';

A situação de non-repeatable read difere de dirty read, pois só foram lidos dados confirmados (dirty read permite leitura de dados não confirmados).


Phantom read

Uma phantom read ocorre quando uma transação executa a mesma leitura mais de uma vez, e recebe mais registros nas leituras subseqüentes, corforme exemplo:

-- usuário 1, retorna "AL - Alabama - South":
SELECT * FROM PUB.state WHERE Region = 'South';

-- usuário 2 insere um novo estado na região sul:
INSERT INTO PUB.state VALUES ('PR', 'Paraná', 'South');

COMMIT;
-- usuário 1 retorna "Alabama" e "Paraná":
SELECT * FROM PUB.state WHERE Region = 'South';
 
Cada um dos níveis de isolamento de transações apresentados anteriormente permite ou previne determinados tipos de problemas de acesso concorrente. Os níveis de isolamento também influenciam nos locks (bloqueios) para as tabelas e registros. No momento da conexão ODBC ou JDBC é possível definir o nível de isolamento padrão para cada conexão. Além disso, é possível alterar o nível de isolamento para cada transação com o comando SET TRANSACTION ISOLATION LEVEL.

Nível de isolamento READ UNCOMMITTED
O nível READ UNCOMMITTED permite todos os problemas descritos anteriormente (dirty read, non-repeatable read e phantom read). As transações que leêm dados neste nível de isolamento não adquirem nenhum tipo de lock nas tabelas nem nos registros. Neste nível de isolamento, as transações não podem modificar dados.
 
Nível de isolamento READ COMMITTED
O nível READ COMMITTED é o recomendado para a maioria das aplicações. Este nível de isolamento previne dirty reads. Non-repeatable reads e phantom reads podem ocorrer. As transações que lêem dados neste nível de isolamento adquirem um lock do tipo IS (intent share) na tabela, e locks do tipo S (shared) nos registros lidos. Os locks de registro são liberados após a leitura do registro, e o lock da tabela é liberado ao término do comando.
 
Nível de isolamento REPEATABLE READ
O nível REPEATABLE READ previne dirty reads e non-repeatable reads. Phantom reads podem ocorrer. As transações que lêem dados neste nível de isolamento adquirem um lock do tipo IS (intent share) na tabela, e locks do tipo S (shared) nos registros lidos. Os locks adquiridos neste nível são os mesmos adquiridos do nível READ COMMITTED. A diferença é que neste nível os locks são liberados somente no final da trasanção, enquando no nível READ COMMITTED eles são liberados assim que os registros são lidos.
 
Nível de isolamento SERIALIZABLE
O nível SERIALIZABLE é o que provê um maior isolamento, e também menor concorrência. Este nível previne todos os problemas apresentados anteriomente (dirty reads, non-repeatable reads e phantom reads). As transações que lêem dados neste nível de isolamento adquirem um lock do tipo S (shared) na tabela inteira. Este lock permanece ativo até o fim da transação. Por conta disso, se uma transação SERIALIZABLE ler qualquer dado de alguma tabela, ninguém poderá realizar alterações nas tabelas lidas.
 
O manual OpenEdge Data Management: SQL Development possui mais detalhes, exemplos e informações sobre os tópicos apresentados neste post.
http://documentation.progress.com/output/OpenEdge102b/pdfs/dmsdv/dmsdv.pdf

Autor: Marcos Kirchner