Oracle Locks

Parte 1

Por Alessandro BAM

Com o advento dos sistemas multi-usuários, um grande problema a ser resolvido é a questão da concorrência pela informação, isto é, a mesma informação pode ser acessada e até mesmo atualizada por vários usuários ao mesmo tempo. Para evitar a interação destrutiva entre essas transações, a grande maioria dos SGBDs disponíveis no mercado possuem algum mecanismo de lock (trava).

A idéia básica atrás desse mecanismo é que quando um usuário modifica um dado através de uma transação, esse dado permanecerá “locado” até que esta seja efetivada (commit) ou desfeita (rollback).

Locks no Oracle

O mecanismo de lock presente no Oracle é um dos mais sofisticados e eficientes dentre os bancos de dados de grande porte, chegando a ser melhor que o de seus maiores concorrentes, SQL Server e DB2.

Mais eficiente, pois, se tomarmos como exemplo esses dois SGBDs acima, veremos que neles todos os locks são gerenciados por uma espécie de lock manager, diferentemente do Oracle, onde esse controle é feito inteiramente no header (cabeçalho) do bloco onde o dado a ser locado reside. Uma boa estratégia, pois isso evita mais um possível ponto de gargalo caso o banco de dados seja massivamente transacional e aumenta a escalabilidade do sistema como um todo.

 

O Oracle faz todo o gerencimento de locks utilizando duas categorias-level: Lock de linha e Lock de tabela.

Lock de linha

Um lock do tipo linha é aplicado individualmente às linhas de uma tabela. Quando uma linha está ““locada””, nenhuma outra sessão conseguirá alterá-la até que a transação que detém o lock chegue ao fim. Claro que se uma determinada linha de uma tabela estiver ““locada”” por uma determinada transação, outros processos poderão sem problema algum alterar as outras linhas dessa tabela que ainda não estejam ““locada”s”.

Lock de tabela

Esse tipo de lock é aplicado no nivel tabela e pode ser utilizado para obter uma imagem consistente da tabela e para assegurar que sua definição não mude enquanto transações ativas ainda existirem nela.

Tipos de Locks

No Oracle, os seguintes tipos de locks são possíveis.

 

Tipo

Level

Row Share (RS)

Tabela

Row Excluive (RX)

Tabela

Share (S)

Tabela

Share Row Exclusive (SSX)

Tabela

Share Row Exclusive (SRX)

Tabela

Exclusive (X)

Tabela/Linha

 

Para entender de forma integral e para usufruir e resolver problemas utilizando a view V$LOCK é importante entender cada um desses tipos de locks. Vejamos a seguir uma explicação de cada um deles.

Row Share (RS)

Também é conhecido com subshare lock (SS), esse lock indica que a transação possui linhas ““locada”s” exclusivamente, mas ainda não as alterou. É obtido através da instrução da Listagem 1.

 

SELECT .....FROM table...FOR UPDATE...

LOCK TABLE table IN ROW SHARE MODE;

Listagem 1. Lock do tipo Row Share.

Um lock RS pode ser utilizado para garantir que a tabela não será “locada” exclusivamente antes de sua transação alterá-la.

Row Exclusive (RX)

Também conhecido como subexclusive lock (SX), esse lock indica que a transação possui linhas “locadas” exclusivamente e já as alterou. É obtido através das instruções da Listagem 2.

 

INSERT INTO tabela...;

UPDATE tabela...;

DELETE FROM tabela...;

LOCK TABLE table IN ROW EXCLUSIVE MODE;

Listagem 2. Lock do tipo Row Exclusive.

Share (S)

Esse tipo de lock é obtido através da instrução da Listagem 3.

 

LOCK TABLE table IN SHARE MODE;

Listagem 3. Lock do tipo Share.

Geralmente o lock S é utilizado para garantir uma imagem consistente da tabela ao longo da transação, isto é, ele garante que nenhum comando DML será permitido. É necessário utilizar essa abordagem, pois o isolation Level default do Oracle é Read Commit, isto é, as alterações efetuadas por outras transações são imediatamente visíveis para todos os usuários logo após serem “comitadas”. Sendo assim, sua transação pode ter várias versões da mesma tabela durante sua duração, o que às vezes não é interessante. Para evitar esse tipo de problema, use um lock S ou inicie a transação com o isolation level definido para Serializable, ou seja, a transação verá somente dados “commitados” até o seu inicio.

 

Atenção:

Quando a tabela está “locada” no modo S, somente a transação que possui o lock pode executar DMLs. Por se tratar de um lock do tipo share, várias transações podem obtê-lo concorrentemente. Caso isso aconteça, nenhuma delas conseguirá efetuar alterações, pois uma estará bloqueando a outra.

Share Row Exclusive (SSX)

Esse tipo de lock é um pouco mais exclusivo que o S, pois somente uma transação pode obtê-lo por vez. Ele permite a outras transações obterem locks em linhas especificas, mas não permite a alteração delas. Esse tipo de lock é obtido através da instrução da Listagem 4.

 

LOCK TABLE table IN SHARE ROW EXCLUSIVE MODE;

Listagem 4. Lock do tipo Share Row Exclusive.

Exclusive (X)

Esse é o mais restritivo lock existente, ele permite apenas que as outras sessões acessem a tabela através de instruções SELECTs, ou seja, nenhum tipo de lock é permitido. Esse lock também é o único lock que pode ser aplicado a linhas. Quando uma linha está “locada”, ela está “locada” exclusivamente e nenhuma transação conseguirá alterá-la até que a transação que mantém o lock chegue ao fim através de um rollback ou commit.

Conclusões

Vários problemas de performance podem estar relacionados ao mecanismo de lock. É necessário conhecê-los para ter sucesso na investigação das causas de tais problemas. No meu próximo artigo, analisaremos alguns casos clássicos como deadlock, esperas por slot na ITL, foreign keys não indexadas entre outros.

 

 Noticia_Alessandro.gif

Alessandro BAM (alessandrobam@gmail.com) é professor interno na Mega Sistemas Corporativos, uma das maiores empresas de software ERP do Brasil, onde leciona cursos da carreira DBA. Como DBA Oracle cerficado trabalha na IBM do Brasil.