Question

I ran into a bit of confusion. I'm under the belief that database operations are automatic - that is either the query succeeds or the transaction is automatically rolledback. For example - if you have a long running UPDATE statement and you "cancel" it before it finishes - IE clicking red circle X button in SQL Developer (which you should receive a ORA-01013: user requested cancel of current operation error). Upon canceling the query the query is rolled back and no rows were affected. I believe the same should hold true for DELETE statements.

I looked around for some documentation on it and I found this article that really isn't authoritative.

Was it helpful?

Solution

If you do that, the statement is rolled back, not the transaction. Below I hit Ctrl+C after starting the UPDATE.

SQL> drop table t1 purge;

Table dropped.

SQL> create table t1 as select * from dba_objects;

Table created.

SQL> insert into t1 select * from t1;

23849 rows created.

SQL> insert into t1 select * from t1;

47698 rows created.

SQL> insert into t1 select * from t1;

95396 rows created.

SQL> insert into t1 select * from t1;

190792 rows created.

SQL> insert into t1 select * from t1;

381584 rows created.

SQL> commit;

Commit complete.

SQL> conn bp/bp
Connected.
SQL> select name, value from v$mystat mt join v$statname sn on (mt.statistic# = sn.statistic#) where sn.name in ('transaction rollbacks', 'rollback changes - undo records applied');

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
rollback changes - undo records applied                                   0
transaction rollbacks                                                     0

SQL> set timing on
SQL> update t1 set object_id = object_id + 1;
update t1 set object_id = object_id + 1
       *
ERROR at line 1:
ORA-01013: user requested cancel of current operation


Elapsed: 00:00:01.51

SQL> select name, value from v$mystat mt join v$statname sn on (mt.statistic# = sn.statistic#) where sn.name in ('transaction rollbacks', 'rollback changes - undo records applied');

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
rollback changes - undo records applied                              173323
transaction rollbacks                                                     1

Elapsed: 00:00:00.00
SQL>

1 transaction was rolled back and 173323 undo records were applied to perform the rollback. But that is because I had no other change in that transaction.

If I have other changes in the transaction, those changes will not be rolled back automatically:

SQL> conn bp/bp
Connected.
SQL> select name, value from v$mystat mt join v$statname sn on (mt.statistic# = sn.statistic#) where sn.name in ('transaction rollbacks', 'rollback changes - undo records applied');

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
rollback changes - undo records applied                                   0
transaction rollbacks                                                     0

Elapsed: 00:00:00.00
SQL> insert into t1(object_id) values (-1);

1 row created.

Elapsed: 00:00:00.00
SQL> select count(*) from t1 where object_id = -1;

  COUNT(*)
----------
         1

Elapsed: 00:00:00.09
SQL> select name, value from v$mystat mt join v$statname sn on (mt.statistic# = sn.statistic#) where sn.name in ('transaction rollbacks', 'rollback changes - undo records applied');

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
rollback changes - undo records applied                                   0
transaction rollbacks                                                     0

Elapsed: 00:00:00.00
SQL> update t1 set object_id = object_id + 1;
update t1 set object_id = object_id + 1
       *
ERROR at line 1:
ORA-01013: user requested cancel of current operation


Elapsed: 00:00:02.16

SQL> select name, value from v$mystat mt join v$statname sn on (mt.statistic# = sn.statistic#) where sn.name in ('transaction rollbacks', 'rollback changes - undo records applied');

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
rollback changes - undo records applied                              274294
transaction rollbacks                                                     0

Elapsed: 00:00:00.01
SQL> select count(*) from t1 where object_id = -1;

  COUNT(*)
----------
         1

Elapsed: 00:00:00.04
SQL> rollback;

Rollback complete.

Elapsed: 00:00:00.00
SQL> select count(*) from t1 where object_id = -1;

  COUNT(*)
----------
         0

Elapsed: 00:00:00.06
SQL> select name, value from v$mystat mt join v$statname sn on (mt.statistic# = sn.statistic#) where sn.name in ('transaction rollbacks', 'rollback changes - undo records applied');

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
rollback changes - undo records applied                              274295
transaction rollbacks                                                     1

Elapsed: 00:00:00.00

Notice how the value of transaction rollbacks remained 0 this time, and how the INSERT was not rolled back, and I was still able to rollback the transaction manually.

Licensed under: CC-BY-SA with attribution
Not affiliated with dba.stackexchange
scroll top