Home » SQL & PL/SQL » SQL & PL/SQL » Trigger fires on deletion of uncommitted data and changes saved (Oracle Database 11g Release 11.1.0.7.0 - 64bit Production Windows)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| Re: Trigger fires on deletion of uncommitted data and changes saved [message #573294 is a reply to message #573293] |
Wed, 26 December 2012 06:50   |
 |
Andrey_R
Messages: 137 Registered: January 2012 Location: Euro-Asia
|
Senior Member |

|
|
Yes, it will fire after the triggered DML, yet, when rollback is performed - the insert performed by the trigger will rollback too.
This creates an impression that the transaction in the trigger depends on the commit or rollback of the DML's,
But I understand that it *actually* depends on the ROLLBACK or COMMIT of the triggering session(yes, I understand, whole session, not transaction).
So, the question asked is(again...):
In the presented scenario, is it possible to know whether an actual *committed* row was deleted from a table, or an uncommitted one?
Can we capture only deletion of committed rows by a trigger/other method?
Regards,
Andrey
[Updated on: Wed, 26 December 2012 06:51] Report message to a moderator
|
|
|
|
| Re: Trigger fires on deletion of uncommitted data and changes saved [message #573295 is a reply to message #573294] |
Wed, 26 December 2012 07:04   |
Solomon Yakobson
Messages: 1398 Registered: January 2010
|
Senior Member |
|
|
I still struggle to understand your question. You start a session. Session issues DELETE from testtab table. Before delete row level trigger fires and inserts a row into testtab_del table. Then row which caused trigger to fire is deleted from testtab table. At this point if you commit both insert into testtab_del and delete from testtab will be committed. And both will be rolled back if if you rollback. You want to commit/rollback delete from testtab and insert inro testtab_del separately? Then create trigger as PARGMA AUTONOMOUS_TRANSACTION.
SY.
|
|
|
|
|
|
|
|
|
|
| Re: Trigger fires on deletion of uncommitted data and changes saved [message #573303 is a reply to message #573298] |
Wed, 26 December 2012 09:33   |
 |
Andrey_R
Messages: 137 Registered: January 2012 Location: Euro-Asia
|
Senior Member |

|
|
Michel Cadot wrote on Wed, 26 December 2012 16:12Quote:I understand now better that a commit or rollback applies to all session, not only to a transaction,
In the end, you don't understand what is a transaction.
Saying that a commit or rollback applies to all sessions is just wrong. It applies and actually ends the current transaction. What "apply" to all OTHER sessions/transactions is (but nothing is actually applied) the visibility of the modifications made the completed transaction.
Commit or rollback is irrelevant to the current transaction; how it ends does not change anything of what it has done, only the persistency of this work.
Once again, read Database Concepts
Chapter 1 Introduction to the Oracle Database
Section Overview of Transactions
Chapter 4 Transaction Management
Section Introduction to Transactions
Regards
Michel
I said all session, not sessionS.
What I meant was the *whole* session(one session, not all).
Ok, I have got the phrase wrong, but there's no need to kill me for that(and save your docs, they were written by people, not the other way around).
>>>>As far as I can tell, you are wrong (again). You never issued a COMMIT, so nothing (not INSERT, not DELETE) was committed
Well, I've posted my code, and it shows clearly that a commit was issue, so I don't understand what you are talking about.
SQL> commit;
Commit complete.
Regards,
Andrey
[Updated on: Wed, 26 December 2012 09:36] Report message to a moderator
|
|
|
|
|
|
|
|
|
|
| Re: Trigger fires on deletion of uncommitted data and changes saved [message #573317 is a reply to message #573310] |
Wed, 26 December 2012 10:56   |
 |
Littlefoot
Messages: 16958 Registered: June 2005 Location: Croatia, Europe
|
Senior Member Account Moderator |
|
|
Let me try with some examples.
SQL> create table testtab (tcol varchar2(100));
Table created.
SQL> create table testtab_del (tcol varchar2(100));
Table created.
SQL> create or replace trigger test_trg
2 before delete on testtab
3 for each row
4 begin
5 insert into testtab_del values (:old.tcol);
6 end;
7 /
Trigger created.
SQL> insert into testtab values ('val1');
1 row created.
SQL> -- it is irrelevant whether you COMMIT here or not. ROLLBACK would matter, though,
SQL> -- because there wouldn't be any row in the TESTTAB table.
SQL> -- Let's try ROLLBACK:
SQL> rollback;
Rollback complete.
SQL> delete from testtab where tcol = 'val1';
0 rows deleted.
SQL> select * from testtab_del;
no rows selected
SQL> -- of course, there's nothing there as we deleted 0 records
SQL>
SQL> insert into testtab values ('val1');
1 row created.
SQL> -- Let's try COMMIT:
SQL> commit;
Commit complete.
SQL> delete from testtab where tcol = 'val1';
1 row deleted.
SQL> select * From testtab_del;
TCOL
--------------------------------------------------------------------------------
val1
SQL> -- the same result as you got (and you didn't commit). If you commit now,
SQL> -- DELETE will become permanent and
SQL> -- a) there will be no records in TESTTAB table
SQL> -- b) there will be 1 record in TESTTAB_DEL table
SQL> -- So let's try it:
SQL> commit;
Commit complete.
SQL> select * from testtab;
no rows selected
SQL> select * from testtab_del;
TCOL
--------------------------------------------------------------------------------
val1
SQL> -- Moreover, it will be permanent "forever" (even if I disconnect):
SQL> disco
Disconnected from Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - Production
With the Partitioning, OLAP and Data Mining options
SQL> connect scott/tiger@ora10
Connected.
Session altered.
SQL> select * from testtab;
no rows selected
SQL> select * from testtab_del;
TCOL
--------------------------------------------------------------------------------
val1
SQL> -- See? Permanent. Let's see what happens with ROLLBACK.
SQL> delete from testtab_del;
1 row deleted.
SQL> commit;
Commit complete.
SQL> insert into testtab values ('val1');
1 row created.
SQL> delete from testtab;
1 row deleted.
SQL> select * from testtab;
no rows selected
SQL> select * from testtab_del;
TCOL
--------------------------------------------------------------------------------
val1
SQL> -- Rollback:
SQL> rollback;
Rollback complete.
SQL> select * from testtab;
no rows selected
SQL> select * from testtab_del;
no rows selected
SQL> -- No record in any of these tables. Why? Because ROLLBACK reverted the INSERT
SQL> -- statement as well, not only the DELETE.
SQL> -- Once again, but this time commit the INSERT.
SQL> insert into testtab values ('val1');
1 row created.
SQL> commit;
Commit complete.
SQL> delete from testtab;
1 row deleted.
SQL> select * from testtab;
no rows selected
SQL> select * from testtab_del;
TCOL
--------------------------------------------------------------------------------
val1
SQL> -- Rollback - at this point - will rollback only the DELETE; INSERT isn't affected
SQL> -- because it was already committed.
SQL> rollback;
Rollback complete.
SQL> select * from testtab;
TCOL
--------------------------------------------------------------------------------
val1
SQL> select * from testtab_del;
no rows selected
SQL>
Finally, if I may, the autonomous transaction: along with a trigger it is a good mechanism for logging changes because even if you rollback the main transaction, insert into the log table isn't affected by that command.
SQL> drop table testtab;
Table dropped.
SQL> drop table testtab_del;
Table dropped.
SQL> create table testtab (tcol varchar2(100));
Table created.
SQL> create table testtab_del (tcol varchar2(100));
Table created.
SQL> create or replace trigger test_trg
2 before delete on testtab
3 for each row
4 declare
5 pragma autonomous_transaction;
6 begin
7 insert into testtab_del values (:old.tcol);
8 commit;
9 end;
10 /
Trigger created.
SQL> -- Note the COMMIT statement within the trigger; normally, you can't commit in a
SQL> -- trigger, but autonomous transaction allows you to do that.
SQL> insert into testtab values ('val1');
1 row created.
SQL> commit;
Commit complete.
SQL> delete from testtab;
1 row deleted.
SQL> -- Obviously, there's no record in TESTTAB, but it is inserted into the TESTTAB_DEL:
SQL> select * from testtab;
no rows selected
SQL> select * from testtab_del;
TCOL
--------------------------------------------------------------------------------
val1
SQL> -- ROLLBACK now. Previously, without the autonomous transaction, the result was:
SQL> -- record was put back into the TESTTAB and removed from TESTTAB_DEL.
SQL> -- With the autonomous transaction, record is put back into the TESTTAB, but - because
SQL> -- of COMMIT in a trigger - the record remains in TESTTAB_DEL.
SQL> rollback;
Rollback complete.
SQL> select * from testtab;
TCOL
--------------------------------------------------------------------------------
val1
SQL> select * from testtab_del;
TCOL
--------------------------------------------------------------------------------
val1
SQL>
|
|
|
|
| Re: Trigger fires on deletion of uncommitted data and changes saved [message #573321 is a reply to message #573317] |
Wed, 26 December 2012 12:25  |
 |
Michel Cadot
Messages: 54155 Registered: March 2007 Location: Nanterre, France, http://...
|
Senior Member Account Moderator |
|
|
Quote:the autonomous transaction: along with a trigger it is a good mechanism for logging changes because even if you rollback the main transaction, insert into the log table isn't affected by that command.
And to clearly specify, is not a good practice to archive deleted rows for the same reason as your example clearly shows it.
Regards
Michel
|
|
|
|
Goto Forum:
Current Time: Tue May 21 03:30:22 CDT 2013
Total time taken to generate the page: 0.10900 seconds
|