drop table conta;
create table conta(
id char(1) not null,
valor number(5,2) not null);
--***************************************************************************
-- >>> SIMULANDO ATUALIZAÇÃO PERDIDA <<<
-- considere que a transação T transfere 20 da conta A para a conta B
-- considere que a transação U transfere 80 da conta C para a conta B
delete from conta;
insert into conta values( 'A', 100);
insert into conta values( 'B', 200);
insert into conta values( 'C', 300);
commit;
-- >>>> operações da transação T <<<<
-- a instrução SERVEROUTPUT informa ao mecanismo PL/SQL que você quer
-- que ele imprima no console principal o ARGUMENT/VALUES que está sendo
-- passado dentro do dbms_output.put_line.
-- a instrução deve ser colocada antes do comando DECLARE
set serveroutput on size unlimited
declare
saldo_A number;
saldo_B number;
saldo_C number;
begin
dbms_output.put_line('>>> SIMULANDO ATUALIZAÇÃO PERDIDA <<<');
dbms_output.put_line('>>>> SALDO INICIAL <<<<');
dbms_output.put_line('Transação T transfere 20,00 da conta A para a conta B');
dbms_output.put_line(' ');
select valor into saldo_A from conta where id = 'A';
dbms_output.put_line('Saldo conta A = '||to_char(saldo_A));
select valor into saldo_B from conta where id = 'B';
dbms_output.put_line('Saldo conta B = '||to_char(saldo_B));
dbms_output.put_line(' ');
begin
dbms_lock.sleep(5);
end;
update conta set valor = (saldo_B + 20) where id = 'B';
update conta set valor = saldo_A - 20 where id = 'A';
commit;
dbms_output.put_line('>>>> Saldo após transferência de 20,00 de A para B
<<<<');
select valor into saldo_A from conta where id = 'A';
dbms_output.put_line('Saldo conta A = '||to_char(saldo_A));
select valor into saldo_B from conta where id = 'B';
dbms_output.put_line('Saldo conta B = '||to_char(saldo_B));
dbms_output.put_line(' ');
end;
/
select * from conta;
-- >>>> operações da transação U <<<<
set serveroutput on size unlimited
declare
saldo_B number;
saldo_C number;
begin
dbms_output.put_line('>>> SIMULANDO ATUALIZAÇÃO PERDIDA <<<');
dbms_output.put_line('>>>> SALDO INICIAL <<<<');
dbms_output.put_line('Transação U transfere 80,00 da conta C para a conta B');
dbms_output.put_line(' ');
select valor into saldo_B from conta where id = 'B';
dbms_output.put_line('Saldo conta B = '||to_char(saldo_B));
select valor into saldo_C from conta where id = 'C';
dbms_output.put_line('Saldo conta C = '||to_char(saldo_C));
dbms_output.put_line(' ');
update conta set valor = (saldo_B + 80) where id = 'B';
update conta set valor = saldo_C - 80 where id = 'C';
commit;
dbms_output.put_line('>>>> Saldo após transferência de 80,00 de C para B
<<<<');
select valor into saldo_B from conta where id = 'B';
dbms_output.put_line('Saldo conta B = '||to_char(saldo_B));
select valor into saldo_C from conta where id = 'C';
dbms_output.put_line('Saldo conta C = '||to_char(saldo_C));
dbms_output.put_line(' ');
end;
/
select c.id, c.valor from conta c;
--***************************************************************************
-- >>> SIMULANDO RECUPERAÇÕES INCONSISTENTES <<<
-- considere que a transação V transfere 20 da conta A para a conta B
-- considere que a transação W calcula a soma dos saldos das contas A, B e C
delete from conta;
insert into conta values( 'A', 200);
insert into conta values( 'B', 200);
insert into conta values( 'C', 300);
commit;
-- >>>> operações da transação V <<<<
set serveroutput on size unlimited
declare
saldo_A number;
saldo_B number;
saldo_C number;
total number := 0;
begin
dbms_output.put_line('>>> SIMULANDO RECUPERAÇÕES INCONSISTENTES <<<');
dbms_output.put_line('>>>> SALDO INICIAL <<<<');
dbms_output.put_line('Transação V transfere 20,00 da conta A para a conta B');
select valor into saldo_A from conta where id = 'A';
dbms_output.put_line('Saldo conta A = '||to_char(saldo_A));
select valor into saldo_B from conta where id = 'B';
dbms_output.put_line('Saldo conta B = '||to_char(saldo_B));
dbms_output.put_line(' ');
update conta set valor = saldo_A - 100 where id = 'A';
commit;
dbms_output.put_line('Saldo conta A = '||to_char(saldo_A - 100));
begin
dbms_lock.sleep(5);
end;
update conta set valor = (saldo_B + 100) where id = 'B';
commit;
dbms_output.put_line('>>>> Saldo após transferência de 100,00 de A para B
<<<<');
select valor into saldo_A from conta where id = 'A';
dbms_output.put_line('Saldo conta A = '||to_char(saldo_A));
select valor into saldo_B from conta where id = 'B';
dbms_output.put_line('Saldo conta B = '||to_char(saldo_B));
dbms_output.put_line(' ');
select sum(SUM(valor)) OVER () as acumulado into total from conta;
dbms_output.put_line('Soma dos saldos das contas A, B e C = '||to_char(total));
dbms_output.put_line(' ');
end;
/
-- >>>> operações da transação W <<<<
set serveroutput on size unlimited
declare
saldo_A number;
saldo_B number;
saldo_C number;
total number := 0;
begin
dbms_output.put_line('>>> SIMULANDO RECUPERAÇÕES INCONSISTENTES <<<');
dbms_output.put_line('>>>> SALDO INICIAL <<<<');
dbms_output.put_line('Transação W calcula a soma dos saldos das contas A, B e
C');
select valor into saldo_A from conta where id = 'A';
dbms_output.put_line('Saldo conta A = '||to_char(saldo_A));
select valor into saldo_B from conta where id = 'B';
dbms_output.put_line('Saldo conta B = '||to_char(saldo_B));
select valor into saldo_C from conta where id = 'C';
dbms_output.put_line('Saldo conta C = '||to_char(saldo_C));
dbms_output.put_line(' ');
select sum(SUM(valor)) OVER () as acumulado into total
from conta where id in ('A', 'B');
dbms_output.put_line('Soma dos saldos das contas A e B = '||to_char(total));
dbms_output.put_line(' ');
select sum(SUM(valor)) OVER () as acumulado into total
from conta;
dbms_output.put_line('Soma dos saldos das contas A, B e C = '||to_char(total));
dbms_output.put_line(' ');
end;
/
--***************************************************************