How to undo a ROLLBACK in sql? - sql

I am learning Oracle SQL, and after a DELETE command I tried to do a ROLLBACK. The problem is that I pressed by mistake F9 a second time and the ROLLBACK ran once again. Now it has deleted all my INSERTs from the table and I don't know how can I get them back.
I tried to insert again the same queries, but there was a problem with the PK (primary key). Also, I can't delete the table to start all over again because I have other tables using FK (foreign keys) in conjunction with this one.

Unfortunately, you cannot undo a ROLLBACK, just like you cannot undo a COMMIT. This is by design.
What happens when you do ROLLBACK is that all un-commited changes until that point are lost. Calling ROLLBACK twice has no effect if you do not perform any changes between the two invocations.
So the question is : did you COMMIT your INSERTs before running your DELETE ?
if yes : the ROLLBACK just reverted the DELETE command, your INSERTs should not be lost
if no : the ROLLBACK reverted also the INSERTs
In both scenarios it does not matter whether your called ROLLBACK once or twice.

You can't undo a rollback. Rollback isn't an "undo" so it has no "redo". It's "throw these changes away, I don't want them"
I would suggest you start a second question where you explain what you meant by: "there was a problem with the PK (primary key)." and ask for help with that.
There's no way back, the only way is forward.

Related

What happens when database shut down before triggers executed?

Assume I have table in PostgreSQL as follows:
CREATE TABLE A
(
userid integer,
productid integer,
description citext,
price numeric
)
and some triggers on it:
CREATE TRIGGER afterinsert
AFTER INSERT
ON A
FOR EACH ROW
EXECUTE PROCEDURE DoSomething1();
CREATE TRIGGER beforeinsert
BEFORE INSERT
ON A
FOR EACH ROW
EXECUTE PROCEDURE DoSomething2();
Now, if I do this:
Insert into A values (1,3,'some description',100.5)
What will happen is:
beforeinsert run DoSomething2()
the row is inserted to A
afterinsert run DoSomething1()
My question is what happens if between 2 and 3 the database shuts down?
when it starts again... what will hapen? will it roll back both the inserted row and roll back beforeinsert trigger?
Basically I just don't understand what is considered the Atomic operation in this case. is it the Insert + triggers or just the row?
The triggers are part of the transaction, and it won't commit until they've finished running. If the database shuts down before the transaction commits, it'll be rolled back. The rollback affects all changes that were made in the transaction, including the changes made by the triggers.
If you do a soft shutdown (that is, tell the database to shutdown: pg_ctl -m fast), it will rollback all open transactions. This includes all changes made by any trigger so far.
If you kill the database (like a kill -9), the database has no chance to properly commit or rollback everything. Next time you start the database, it will run a recovery and rollback all the changes to the point of the last successful commit.
All triggers are part of the ongoing transactions, all changes are only committed once all AFTER triggers finish.

When exactly is an AFTER DELETE trigger fired

I hope that you can help me on some SQL theory, as I am not 100% sure how this works.
If I have a trigger and I define it as
AFTER DELETE ON xxxx
I was wondering when exactly this would fire, in terms of transaction management?
So if I delete a record from my table I assume that the trigger will not fire until I type commit and finish the transaction. Is this correct?
If so, then I assume that if the commit on my delete statement works but the trigger fails for some reason then only the trigger would be rolled back, and the original executed delete statement that I performed would still be committed (because I have it defined as AFTER DELETE).
Can somebody please confirm this?
Thanks.
1. You delete a row on TABLE1 no COMMIT;
2. TRIGGER performs an action (This takes place before COMMIT or ROLLBACK for step1, but trigger will not have any commit or rollback in it)
3a. You apply commit - Both step1 and step2 gets completed .
3b. You apply rollback- Both step1 and step2 rolled back.
Either you give 3a or 3b
The purpose of SQL triggers is to ensure referential consistency. But when they would be exectued in a separate transaction commit, there would be the possibility that they leave data in an inconsistent state.
So the delete trigger is executed the moment you do the delete command. When this happens as a transaction and you roll it back, the triggered delete is also rolled back.
An AFTER DELETE trigger is fired after the delete statement is executed, and before the control is returned to the user - i.e., he perceives the delete statement and the code executed after it in a trigger as a single action (assuming the trigger just does DMLs and nothing funky like calling UTL_TCP :-)).
This has nothing to do with transaction management - once the DELETE and the AFTER DELETE trigger execute, you can choose to commit, to rollback, or to continue performing DML statements in the same transaction.

How to rollback delete command without using transaction

How to rollback delete command without using transaction ? if we can't , then what's the difference between Truncate & delete ?
You cannot rollback in this case, but when you are using the Full Recovery Model, then you can turn your database back to the moment before you issued the delete command.
You cannot ROLLBACK an operation without a transaction. You could probably use implicit transactions, but you still need to call COMMIT or ROLLBACK explicitly. However, for better control, it's better to wrap the statement(s) in a BEGIN TRANSACTION...COMMIT / ROLLBACK block anyway. This way you'll avoid any confusion and the need to use the IMPLICIT_TRANSACTION setting.
You can roll back DELETE or TRUNCATE (and most other operations) if and only if they are part of a transaction that's not yet committed. Alternatively you could restore the deleted/truncated data from a backup.
There are several differences between TRUNCATE and DELETE. Most notably TRUNCATE can only empty a table whereas DELETE deletes just the rows you specify. TRUNCATE deallocates and logs data at the page level instead of row level, which typically makes TRUNCATE a more efficient method than DELETE for deleting the entire content of a table.

How to stop oracle undo process?

I want to know how to stop undo process of oracle ? I tried to delete millions of rows of a big table and in the middle of process I killed session but It started to undo delete and for a bout two hours database got dramatically slow. I didn't want the undo process to be continued. Is there any way to stop it ?
You can't stop the process of rolling back the transaction because doing so would leave the database in an inconsistent state.
When you are executing a long-running delete process, Oracle will likely be writing the changed blocks to your data files before you decide whether to commit or rollback the transaction. If you interrupted the process in the middle of executing the transaction, there will be some changed blocks on disk, some changed blocks in memory, and some unchanged blocks. Rolling back the transaction is the only way to return the database to the state it was in before you started executing the DELETE statement.
Row-by-row delete processes can, as you've found, be exceedingly slow. If the deletions are all done in a single transaction, as appears to be the case here, they can become even slower. You might want to consider the following options:
If you're deleting all the rows in the table you might want to consider using the TRUNCATE TABLE statement.
If you're not deleting all the rows in the table you should probably change your procedure to COMMIT after a certain number of rows are deleted.
In the meantime you're going to have to wait until that rollback process completes.
Share and enjoy.
and when you try truncating the table while it's still deleting you'll be seeing an ORA-00054 "resource busy and acquire with NOWAIT specified or timeout expired"

Do queries executed in a Postgres trigger procedure run in the same transaction?

I have a BEFORE DELETE trigger which inserts rows into another table using SPI_exec.
Do these INSERT queries run in the same transaction as the one in which the original delete is executing? Hence, will the delete and all inserts roll back or commit together?
If not, how can I make that happen?
Yes, everything in triggers is in the same transaction as the triggering event.
Not directly related to the question, but normally you want to put side-effects in the AFTER trigger, rather than the BEFORE trigger.