Nesse primeiro Post, tenho a intenção de mostrar de forma resumida, prática e simples o conceito de concorrência e consistência de dados, enfim os nossos locks de cada dia.
Se os banco de dados tivessem apenas um único usuário, muitos dos nossos problemas seriam resolvidos (Tudo bem que criaríamos muitos outros, mas isso não vem ao caso agora), os dados poderiam sofrer modificações em diversas horas e até ao mesmo tempo. Porém como dois corpos não ocupam o mesmo lugar no espaço, em bancos de dados "multi usuário", as transações podem tentar atualizar os mesmos dados ao mesmo tempo. Então por isso os bancos de dados devem ter e possuem um controle de concorrência afim de manter a consistência dos dados, para os outros usuários.
Concorrência de Dados quer dizer que os usuários(vários) podem acessar os mesmos dados ao mesmo tempo. Já Consistência de dados quer dizer que os usuários podem ter uma visão consistente sólida e real dos dados, incluindo as alterações que o próprio usuário esta realizando e as alterações feitas por outros usuários.
Help_1: Caso algum iniciante tenha a seguinte dúvida:
- Se algum usuário estiver atualizando uma tabela, eu vou ver os valores antigos ou os alterados ?
Resposta : Em primeiro lugar, caso você tenha essa dúvida é sinal que está na hora de aprender sobre segmentos de UNDO, mas
Mecanismo de Locks (Ou bloqueio)
Os SGBDs tem por default um mecanismo de lock(bloqueio) para resolver os problemas realcionados a integridade, consistência e concorrência de dados. Os Locks são mecanismos que impedem que transações atualizem os mesmos dados ao mesmo tempo.
- Controlam o acesso concorrente ao banco de dados
- Impede atualizações simultâneas do mesmo dado
- È liberado ao final de cada transação (COMMIT,ROLLBACK)
Tempo de Duração
Todos os bloqueios adquiridos pelas declarações dentro de uma transação são mantidos para a duração da operação, impedindo a interferência destrutiva, incluindo leituras sujas e perda de atualizações. As alterações introduzidas pelas instruções SQL de uma transação só se tornam visíveis para outras transações que começam após que a primeira transação seja confirmada (Commit).O Oracle libera todos os bloqueios adquiridos pelas declarações dentro de uma transação quando você confirmar ou desfazer a transação. A Oracle também libera os bloqueios adquiridos após um ponto de salvamento(savepoint) quando existe reversão para o ponto de salvamento.
DEADLOCK
Um deadlock ocorre quando dois ou mais segmentos do controle estão bloqueadas, cada um à espera de um recurso mantido por outro segmento.Elas ficam aguardando que uma libere um determinado recurso para que outra o utilize. Existe outras fontes na internet os quais detalham melhor esse conceito e os tipos de Lock.( http://profissionaloracle.com.br/blogs/drbs/page/2/)
A Nível de Teste vamos forçar o acontecimento de Locks.
1_Vamos Criar e popular a tabela HT_LOCK.SQL> CREATE TABLE HT_LOCK (
ID_LOCK VARCHAR2(1),
COD_LOCK VARCHAR2(1));
Table created.
SQL> INSERT INTO HT_LOCK VALUES (1,'A');
SQL> INSERT INTO HT_LOCK VALUES (2, 'B');
SQL> INSERT INTO HT_LOCK VALUES (3, 'C');
SQL> INSERT INTO HT_LOCK VALUES (4, 'D');
4 row created.
SQL> SELECT * FROM HT_LOCK;
ID_LOCK COD_LOCK
--- ---
1 A
2 B
3 C
4 D
4 rows selected.
SQL> commit ;
Commit complete.
2_Vamos efetuar um UPDATE nessa Tabela com usuários diferentes;
SQL>UPDATE HT_LOCK SET ID_LOCK='0' WHERE ID_LOCK='4';
1 linha atualizada.
SQL> UPDATE HUDSON.HT_LOCK SET ID_LOCK='9' WHERE ID_LOCK='2';
1 linha atualizada.
3_Agora vamos verificar quais usuários estão gerando algum tipo de lock.
SQL> SELECT OBJECT_ID,SESSION_ID,ORACLE_USERNAME FROM V$LOCKED_OBJECT;
OBJECT_ID SESSION_ID ORACLE_USERNAME
---------- ---------- ------------------------------
19996 14 HUDSON
19996 21 SYSTEM
2 linhas selecionadas.
Help_2 A Visão V$LOCKED_OBJECT listas todos os bloqueios adquiridos por todas as transações no sistema. Isso mostra que as sessões estão mantendo bloqueios DML em que objetos e de que modo.
Então Temos dois Usuários com locks em um objeto de mesmo ID, logo se trata do mesmo objeto..
Agora vamos descobrir que objeto é esse ;
SQL> SELECT OBJECT_NAME, OBJECT_TYPE,OBJECT_ID FROM DBA_OBJECTS WHERE OBJECT_ID = 19996;
OBJECT_NAME OBJECT_TYPE OBJECT_ID
------------------------------ ------------------- ------ ----
HT_LOCK TABLE 19996
Agora sabemos que esse lock é realizado na Tabela HT_LOCK .
Eu mostrei como localizar quais são os usuários os quais estão gerando lock em alguma tabela e quais tabelas são essas de forma separada para melhor entendimento, mas isso também poderia ser feito de uma forma só com o select abaixo :
SQL>SELECT A.OBJECT_ID, A.SESSION_ID, A.ORACLE_USERNAME, B.OBJECT_NAME , B.OBJECT_TYPE FROM v$locked_object A , DBA_OBJECTS B
WHERE A.OBJECT_ID = B.OBJECT_ID;
OBJECT_ID SESSION_ID ORACLE_USERNAME OBJECT_NAME
--------------- --------------- ------------------------------ ----------------------------------
19996 21 SYSTEM HT_LOCK
19996 14 HUDSON HT_LOCK
Agora se um sessão de um usuário gerar um lock em alguma tabela e se a mesma for mal finalizada ela ira ficar com o status de inativa no banco de dados, e esse lock somente irá sumir quando o processo de segundo plano ou background PMON aplicar rollback na transação, e assim remover os locks nas linhas afetadas.
Mas caso por algum problema PMON demorar para aplicar o rollback e remover os locks, você pode matar essa sessão pendente e assim retirar o lock, da seguinte forma.
SQL> SELECT SID,SERIAL#,USERNAME,STATUS FROM V$SESSION WHERE SID = 14 --(ESSE VALOR É EQUIVALENTE AO VALOR DO CAMPO SESSION_ID DA VISÃO v$locked_object)
SID SERIAL# USERNAME STATUS
-------- ---------- ------------------------------ --------
14 61 HUDSON INACTIVE
Após obter o SID, e o SERIAL# de sessão vamos forçar a sua finalização com o comando :
ALTER SYSTEM KILL SESSION '301,9797' IMMEDIATE;
A Minha intenção nesse Post foi mostrar como ocorre um lock e como entender o processo de identificação e finalização :
Porém existem scripts que podem fazer tudo, ou andar um bom caminho segue esse script do Rodrigo Almeida publicado em 06 novembro 2005 ás 15:03 no link :
http://forum.imasters.uol.com.br/index.php?/topic/153638-monitoracao-de-objetos-em-lock/
SET LINESIZE 500
SET PAGESIZE 1000
SET VERIFY OFF
COLUMN owner FORMAT A20
COLUMN username FORMAT A20
COLUMN object_owner FORMAT A20
COLUMN object_name FORMAT A30
COLUMN locked_mode FORMAT A15
SELECT b.session_id AS sid,
NVL(b.oracle_username, '(oracle)') AS username,
a.owner AS object_owner,
a.object_name,
Decode(b.locked_mode, 0, 'None',
1, 'Null (NULL)',
2, 'Row-S (SS)',
3, 'Row-X (SX)',
4, 'Share (S)',
5, 'S/Row-X (SSX)',
6, 'Exclusive (X)',
b.locked_mode) locked_mode,
b.os_user_name
FROM dba_objects a,
v$locked_object b
WHERE a.object_id = b.object_id
ORDER BY 1, 2, 3, 4;
SET PAGESIZE 14
SET VERIFY ON
Bibliografia utilizada :
- Oracle Database 11g /Bob Byla e Kevin Loney
- Dominando o Oracle 9i Damaris Fanderuff
- http://download.oracle.com/docs/cd/B19306_01/server.102/b14220/consist.htm#i5704
Muito bacana seu post! Me esclareceu bastante!
ResponderExcluirFera seu post, ajudou bastante!!!
ResponderExcluir