As you've noted, rollback is essentially the database running the opposite statement to reverse the changes. So the factors that affect it are similar to those affecting the speed of DML in the first place, e.g:
* How many statements you run (more => longer)
* How much data you're changing (more => longer)
* The types of statement (insert/update/delete)
* Whether there are any indexes, triggers, etc. on the tables that also need reversing
* ...
Essentially the more stuff there is to rollback the longer it'll take.
Why does it generally take more than the time it took for the actual transactionThis may have been true in the past. Running on 19.22, rollback takes similar or less time for many operations.
For example, with this table:
SQL> create table t ( c1 int primary key, c2 varchar2(100) default rpad ( 'stuff', 50, 'f' ));
InsertsSQL> set timing on
SQL> begin
2 for i in 1 .. 1000000 loop
3 insert into t ( c1 ) values ( i );
4 end loop;
5 end;
6 /
PL/SQL procedure successfully completed.
Elapsed: 00:00:35.47
SQL>
SQL> rollback;
Rollback complete.
Elapsed: 00:00:25.01
SQL>
SQL> insert into t ( c1 ) select level from dual connect by level <= 1000000;
1000000 rows created.
Elapsed: 00:00:01.85
SQL>
SQL> rollback;
Rollback complete.
Elapsed: 00:00:00.50
In both cases, rollback was notably faster than the insert. Adding and undoing single-row inserts was significantly slower than one insert loading all the data.
Let's add data back to run the other changes:
insert into t ( c1 ) select level from dual connect by level <= 1000000;
commit;
UpdatesSQL> update t
2 set c2 = null;
1000000 rows updated.
Elapsed: 00:00:26.63
SQL> rollback;
Rollback complete.
Elapsed: 00:00:27.14
SQL>
SQL> update t
2 set c2 = lpad ( 'stuff', 100, 'f' );
1000000 rows updated.
Elapsed: 00:00:37.91
SQL> rollback;
Rollback complete.
Elapsed: 00:00:33.77
Here rollback is roughly the same amount of time as the update.
DeletesSQL> delete t;
1000000 rows deleted.
Elapsed: 00:00:46.14
SQL> rollback;
Rollback complete.
Elapsed: 00:00:46.69
SQL>
SQL> begin
2 for i in 1 .. 1000000 loop
3 delete t where c1 = i;
4 end loop;
5 end;
6 /
PL/SQL procedure successfully completed.
Elapsed: 00:01:07.80
SQL> rollback;
Rollback complete.
Elapsed: 00:00:45.99
Rollback takes about the same amount of time as a single delete of all the data, whether it's removed row-by-row (which is notably slower) or all in one go.
For complex transactions involving many tables you may get different results. If you want to know how long it'll take to roll back in a given scenario, test it!
How does the objects lock work here is it the same mechanism how the actual DML was doneWhen rolling back update and delete, the rows are still locked! When rollback completes it releases the locks.
When you insert new rows, no other sessions can see them until you commit. There may be locks held on other structures (e.g. unique indexes); again the database will hold these until the transaction is complete (whether by commit or rollback).