create user trx_1 identified by trx_1
default tablespace users
temporary tablespace temp
quota unlimited on users;
create user trx_2 identified by trx_2
default tablespace users
temporary tablespace temp
quota unlimited on users;
create user trx_admin identified by trx_admin
default tablespace users
temporary tablespace temp
quota unlimited on users;
grant all on trx_table to trx_1, trx_2;
insert into trx_table values (1, 'one' );
insert into trx_table values (2, 'two' );
insert into trx_table values (3, 'three');
insert into trx_table values (4, 'four' );
insert into trx_table values (5, 'five' );
commit;
delete from trx_table where id = 1;
update trx_table set tx = 'TWO' where id = 2;
update trx_table set tx = 'THREE' where id = 3;
insert into trx_table values (6, 'SIX');
commit;
update trx_table set tx = 'Three' where id = 3;
update trx_table set tx = 'FOUR' where id = 4;
delete from trx_table where id = 5;
insert into trx_table values (7, 'SEVEN');
commit;
select * from trx_table order by id;
ID TX
---------- ----------
2 TWO
3 Three
4 FOUR
6 SIX
7 SEVEN
--set serveroutput on size 1000000 format wrapped
begin
for r in (
select /*undo_change#,*/ undo_sql
from flashback_transaction_query
where table_name = 'TRX_TABLE' and
table_owner = 'TRX_ADMIN' and
logon_user = 'TRX_1' and
commit_scn > (select scn from after_init_load)
order by undo_change#
) loop
-- dbms_output.put_line('r.undo_change#: ' || r.undo_change#);
-- dbms_output.put_line(' ' || r.undo_sql);
execute immediate
substr(r.undo_sql, 1, length(r.undo_sql)-1); --remove trailing ';'
end loop;
end;
/
select * from trx_table order by id;
The effect of trx_1's transaction is reversed with almost all of trx_2's changes still in place. The problem is
the row identified by id=3 which (probably) should have tx=Three (uppercase T) as trx_2 changed that row after trx_1 changed it.
ID TX
---------- ----------
1 one
2 two
3 three
4 FOUR
7 SEVEN
|