Transacção |
Uma transacção é um conjunto de instruções SQL que devem funcionar como um todo. Isto significa que uma transacção tem sucesso se todas as suas instruções tiverem sucesso e fracassa se uma das suas instruções falhar. Neste módulo vamos ver:
Como iniciar e terminar uma transacção
Uma transacção pode ser constituída por um ou mais comandos SELECT, INSERT, UPDATE ou DELETE. Em Oracle uma transacção começa logo que termina a transacção anterior. Uma transacção termina numa das seguintes situações:
Quando a transacção termina com confirmação as alterações feitas aos dados tornam-se definitivas. Isto ocorre nestas situações:
Na realidade uma transacção termina apenas com COMMIT ou ROLLBACK, mas os comandos DDL e DCL assim como o fim de sessão normal (EXIT) têm COMMIT implícito, ou seja, a base de dados confirma a sua execução de forma automática.
Quando a transacção termina sem confirmação as alterações feitas aos dados são desfeitas. Isto signnifica que são repostos os valores que os dados tinham no inicio da transacção. Isto ocorre nas seguintes situações:
O exemplo abaixo mostra uma transacção:
Tempo | Sessão 1 | Comentário |
---|---|---|
1 | commit; | Fim da transacção anterior e inicio da nova |
2 |
drop table teste; create table teste ( id number(10,0), nome varchar2(100), constraint pk_teste primary key (id) ); |
Remover a tabela TESTE (caso exista) e recriá-la. São dois comandos DDL, sendo cada um deles uma transacção com COMMIT implícito. Depois do COMMIT implícito do segundo comando inicia-se uma nova transacção. |
3 |
insert into teste (id,nome) values (1,'José'); insert into teste (id,nome) values (2,'João'); insert into teste (id,nome) values (3,'joão'); insert into teste (id,nome) values (4,'joaquim'); insert into teste (id,nome) values (5,'josé'); insert into teste (id,nome) values (6,'Joaquim'); select * from teste; |
Dentro da transacção inserir várias linhas na tabela TESTE e verificar que estão lá. |
4 |
rollback; |
Fazer rollback à transacção |
5 |
select * from teste; |
Verificar que as alterações foram desfeitas, ou seja, os dados voltaram ao valor inicial |
Se no passo 4 tivessemos feito COMMIT em vez de ROLLBACK as alterações tornavam-se definitivas.
SAVEPOINT
O comando ROLLBACK na sua versão simples desfaz todas as alterações feitas na transacção. É possível adicionar SAVEPOINTs ao longo da transacção que permitem o "desfazer" parcial. O exemplo abaixo mostra como:
Tempo | Sessão 1 | Comentário |
---|---|---|
1 |
drop table teste; create table teste ( id number(10,0), nome varchar2(100), constraint pk_teste primary key (id) ); |
Remover a tabela TESTE (caso exista) e recriá-la. São dois comandos DDL, sendo cada um deles uma transacção com COMMIT implícito. Depois do COMMIT implícito do segundo comando inicia-se uma nova transacção. |
2 |
insert into teste (id,nome) values (1,'José'); insert into teste (id,nome) values (2,'João'); insert into teste (id,nome) values (3,'joão'); insert into teste (id,nome) values (4,'joaquim'); insert into teste (id,nome) values (5,'josé'); insert into teste (id,nome) values (6,'Joaquim'); select * from teste; |
Dentro da transacção são inseridas várias linhas na tabela TESTE. Depois verificamos que as linhas estão lá. Estas alterações ainda não foram confirmadas. |
3 |
SAVEPOINT Joao_1; |
Criar o SAVEPOINT Joao_1 |
4 |
update teste set nome='JOAO' where nome = 'joão'; |
Alterar o nome 'joão' para 'JOAO' |
5 |
SAVEPOINT Joao_2; |
Criar o SAVEPOINT Joao_2 |
6 |
select * from teste; |
Verificar que o update anterior foi bem sucedido. A transacção ainda não terminou, pelo que as alterações ainda não são definitivas |
7 |
update teste set nome='JOSE' where nome = 'josé'; |
Alterar o nome 'josé' para 'JOSE' |
8 |
select * from teste; |
Verificar que o update anterior foi bem sucedido. As duas alterações feitas na transacção são visíveis, mas ainda não definitivas. |
9 |
rollback to savepoint Joao_2; |
Desfazer as alterações até ao SAVEPOINT Joao_2 |
10 |
select * from teste; |
Verificar que o update JOSE foi desfeito, mas ainda temos o update JOAO |
11 |
rollback to savepoint Joao_1; |
Desfazer as alterações até ao SAVEPOINT Joao_1 |
12 |
select * from teste; |
Verificar que o update JOAO foi desfeito |
13 |
rollback; |
Desfazer as alterações até ao inicio da transacção |
14 |
select * from teste; |
Verificar que a tabela náo tem linhas. Os comandos INSERT fazem parte da transacção e foram desfeitos. |
Um comando COMMIT executado no meio dos comandos anteriores tornaria as alterações feitas até aí definitivas, e portanto um ROLLBACK posterior não seria capaz de as desfazer.
AUTOCOMMIT
Dentro do ambiente SQL*Plus e em alguns clientes Oracle (por exemplo o TOAD ou o SQL Navigator) existe a opção AUTOCOMMIT que permite a confirmação implicita de um comando logo que termina a sua execução. Quando esta opção está activa cada comando é uma transacção.
Uma alteração a um dado implica o "esmagamento" de um novo valor sobre um valor antigo. Para possibilitar o ROLLBACK da alteração a base de dados necessita guardar o valor antigo, o que ocorre nas seguintes circunstâncias:
Do ponto de vista de desempenho ao activar a opção AUTOCOMMIT estamos a beneficiar a base de dados. Isto porque o volume de dados necessário para fazer ROLLBACK aumenta com o aumento do número de instruções que formam a transacção e neste caso temos apenas uma.
No exemplo abaixo vemos como activar e desactivar a opção AUTOCOMMIT. Esta sintaxe é válida no SQL*PLus:
set autocommit on; |
Realizado por Turtle Learning ®. Última alteração em 2011-02-26