I executed an update statement mistakenly without any where clause in pl/sql developer.I did click on the break button when I found what had happened after some time when the execution was taking time to complete, commit and rollback buttons were grayed out after breaking the execution hence could not roll back the transaction. I am worried if break button commits the transaction in pl/sql developer or it roll backs to the previous state.
PL/SQL Developer's Break key does not commit, it just breaks the current operation and leaves things as they were at the start of it, including any open transactions. For example, if you did three updates without committing, and then started a fourth but used the Break key to interrupt it, you would still have the first three uncommitted updates, and the Commit and Rollback icons would be active.
The icons were greyed out because there was no transaction to commit. PL/SQL Developer sets their status by calling dbms_transaction.local_transaction_id after every statement to check for an open transaction.
If you didn't see the "Are you sure?" warning popup, you might check Configure > User Interface > Options > DSA Dialogs in case you previously clicked "OK" on a "Don't show this message again" popup.
First step is to be cool.. otherwise you won't able to think properly.
Immediately execute Rollback command.
Then run a query to select the updated field and check whether the result contains any values other than updated value.
for example if you executed below query,
update Employees set Status = 'Inactive' you should check whether the status column contains any value other than 'Inactive'
If the column contains any value other than updated value, you are good and fine.
the system rolled back that update statement.
If the column doesn't contains value other than the updated values, please connect with the database administrator to rollback this transaction.
They will able to do this without much hassle.
Related
I have a series data modify operation to do,such as
1. update table_a set value=1 where id=1
2. update table_b set value=2 where id=1
3. update table_c set value=3 where id=1
and I want to ensure this three operation must all complete,I know using transaction can guarantee all performed or none performed.But my point is must make these three all performed.when first sql performed,the app instance may crashed and the other two are missed.
Note this is a ditributed enviroment,may be another app instance can take over the unfinished SQL,but how can I do it?
Can I use a stored procedure,the app instance only fire the stored procedure,and database finsh all the sql?
If when performing transaction,the app instance suddenly crashes,will it leads to a dead lock?
Deadlocks are not crashed requests which fail before the end of the execution. If your request crashes into a transaction, it won't lead to a deadlock.
It is always better to use stored procedures but this won't help you for this specific case.
What I would suggest is inded the use of a transaction with a try catch to rollback the transaction in case of failure.
Something like that :
BEGIN TRY -- start of try
BEGIN TRANSACTION; -- start of transaction
update table_a set value=1 where id=1
update table_b set value=2 where id=1
update table_c set value=3 where id=1
COMMIT TRANSACTION; -- everything went ok we commit
BEGIN CATCH -- an error happened we rollback
PRINT N'Unexpected error';
ROLLBACK TRANSACTION;
END CATCH
You can check more complete examples here
If an app is performing a transaction on a database server, and the app crashes (abruptly disconnects from the database) before committing the transaction, the database server rolls back the transaction. The disconnection does not leave the database in an unusable (potentially deadlocked) state.
So your database contents won't reflect any of your three UPDATE operations when your app crashes during your transaction. It will just lose the transaction in progress.
How to handle this potential failure mode?
Reduce the probability of a crash during a transaction. Try to avoid doing stuff in your app that could make it crash while your transaction is in process. For example, if you get data from some other server or device, get it all before you begin your transaction. This solution is usually good enough for production apps.
Rig up some sort of way for your app, upon restarting, to find out the most recent successful transaction. One good way? Add a column like this to one of your tables: (this is a MySQL thing.)
last_update_timestamp TIMESTAMP DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
This causes every UPDATE operation on each column to -- automatically -- put NOW() into the last_update_timestamp column. Then, when your crashed app restarts you can do
SELECT MAX(last_update_timestamp) FROM table
and you'll know when the most recent successful update occurred. This automatic update also gets rolled back if a transaction is rolled back. If you know when the last successful update occurred, your app may be able to redo the one that was rolled back by the crash.
If you choose to build a redo-transaction capability, be sure to build it so you can test it! if (testingAppCrash) crashNow = 1 / 0; might do the trick in your app.
I don't understand the detailed steps when rolling back using Liquibase.
I had scenario like 6 changesets and for one changeSet rollback was not defined - that is, only <rollback/> within the changeset.
After executing using deployIT I could see 7 entries in Databasechangelog table, 6 for added, one for tag creation due usage of deployIT.
After rolling back I saw the behavior of removing all newly added 6 changesets even though one of the six changesets had an empty rollback tag.
Please any expert tell me why? What is the exact behavior of rollback?
Overall want to know when records from Databasechangelog removed ?
When running rollback, liquibase finds the changeSets to roll back, and then checks for a <rollback> tag in each describing how to roll the changeSet back.
If there is no <rollback> tag, then Liquibase checks if the changes in the changeSet have built-in logic on how to roll themselves back. Like gile pointed out, if there is enough information in the change to undo it (like how the createTable change has the table name needed to drop the table) it will be able to still roll them back.
But if there isn't enough information in the change (like how a dropTable doesn't have the information needed to re-create the table) then the rollback command will fail with a "cannot roll back" error.
So the rollback logic is:
Use what is defined in a block
If no rollback block, try to deduce what is needed
If there isn't enough information to roll back, exit before rolling back
If you specify an empty rollback block, you are telling Liquibase "the logic needed to roll this back is to do nothing", so Liquibase happily runs your no-op rollback command and marks the changeSet as rolled back.
Depending on your change sets, may be you fall in case of statements having rollback commands generated automatically, as for Liquibase Rollback documentation:
Many refactorings such as “create table”, “rename column”, and “add
column” can automatically create rollback statements. If your change
log contains only statements that fit into this category, your
rollback commands will be generated automatically.
Other refactorings such as “drop table” and “insert data” have no
corresponding rollback commands that can be automatically generated.
In these cases, and cases where you want to override the default
generated rollback commands, you can specify the rollback commands via
the tag within the changeSet tag. If you do not want anything done to
undo a change in rollback mode, use an empty tag.
At http://forum.liquibase.org/topic/understanding-rollback you can find more details and other links.
Say I have a query like this:
BEGIN Transaction
UPDATE Person SET Field=1
Rollback
There are one hundred million people. I stopped the query after twenty minutes. Will SQL Server rollback the records updated?
A single update will not update some rows. It will either update all or 0.
So, if you cancel the query, nothing will be updated.
This is atomicity database systems which SQL Server follows.
In other words, you don't have to do that rollback at the end, nothing was committed anyway.
When you cancel a query, it will still hold locks until everything is rolled back so no need to panic.
You could test it yourself, execute the long query, cancel it and you will notice that it takes a while before the process really end.
While the update statement will not complete, the transaction will still be open, so make sure you rollback manually or close out the window to kill the transaction. You can test this by including two statements in your transaction, where the first one finishes and you cancel while it's running the second - you can still commit the transaction after stopping it, and then get the first half of your results.
BEGIN Transaction
UPDATE Person SET Field=1 WHERE Id = 1
UPDATE Person SET Field=1
Rollback
If you start this, give it enough time for the first line to finish, hit the Stop button in SSMS, then execute commit transaction, you'll see that the first change did get applied. Since you obviously don't want part of a transaction to succeed, I'd just kill the whole window after you've stopped it so you can be sure everything's rolled back.
Since you have opened the Transaction, Stoping the Query manually does not completes the transaction, This transaction will still be open and all the subsequent requests to this table will be blocked.
You can do any one of following options
Kill the Connection using the command KILL SPID (SPID is the process ID of your connection)
Note: This will auto rollback the changes you made, you can monitor the rollback status with command KILL SPID WITH STATUSONLY (After killing)
run the ROLLBACK command manually
** SPID is your request id, you can find it from sys.sysprocesses table/ you can also find it on Management Studio query Window the number which is within brackets / also you can find it at bottom right corner of your management studio beside the login name.
Example SQLQuery2.sql... (161) -- 161 is your spid.
I have a problem to solve which requires undo operation of each executed sql file in Oracle Database.
I execute them in an xml file with MSBuild - exec command sqlplus with log in and #*.sql.
Obviously rollback won't do, because it can't rollback already commited transaction.
I have been searching for several days and still can't find the answer. What I learned is Oracle Flashback and Point in Time Recovery. The problem is that I want the changes to be undone only for the current user i.e. if another user makes some changes at the same time then my solution performs undo only on user 'X' not 'Y'.
I found the start_scn and commit_scn in flashback_transaction_query. But does it identify only one user? What if I flashback to a given SCN? Will that undo only for me or for other users as well? I have taken out
select start_scn from flashback_transaction_query WHERE logon_user='MY_USER_NAME'
and
WHERE table_name = "MY_TABLE NAME"
and performed
FLASHBACK TO SCN"here its number"
on a chosen operation's SCN. Will that work for me?
I also found out about Point in Time Recovery but as I read it makes the whole database unavailable so other users will be unable to work with it.
So I need something that will undo a whole *.sql file.
This is possible but maybe not with the tools that you use. sqlplus can rollback your transaction, you just have to make sure auto commit isn't enabled and that your scripts only contain a single commit right before you end the sqlplus session (if you don't commit at all, sqlplus will always roll back all changes when it exits).
The problems start when you have several scripts and you want, for example, to rollback a script that you ran yesterday. This is a whole new can of worms and there is no general solution that will always work (it's part of the "merge problem" group of problems, i.e. how can you merge transactions by different users when everyone can keep transactions open for as long as they like).
It can be done but you need to carefully design your database for it, the business rules must be OK with it, etc.
To general approach would be to have a table which contains the information which rows were modified (= created,updated,deleted) by the script plus the script name plus the time when it was executed.
With this information, you can generate SQL which can undo the changes created by a script. To fill such a table, use triggers or generate your scripts in such a way that they write this information as well (note: This is probably beyond a "simple" sqlplus solution; you will have to write your own data loader for this).
Ok I solved the problem by creating a DDL and DML TRIGGER. The first one takes "extra" column (which is the DDL statement you have just entered) from v$open_cursor and inserts into my table. The second gets "undo_sql" from flashback_transaction_query which is the opposite action of your DML action - if INSERT then undo_sql is DELETE with all necessary data.
Triggers work before DELETE,INSERT (DML) on specific table and ALTER,DROP,CREATE (DDL) on specific SCHEMA or VIEW.
A few minutes ago, while working out a new sproc, I executed the wrong delete statement. Something like this:
Delete From SomeTable Where SomeStatusID=1
10 seconds into it, I realized that I typed in the wrong status and hit cancel. It said that the statement was canceled.
I did a restore to a separate database to get back the table that I just presumably nuked, thinking that since this was not in a transaction some records were probably deleted.
Oddly, the records were all intact. Just curious as to why this was -- did it treat the individual delete statement as a transaction in this case, even though there was not an explicit transaction defined?
By default, a single DML statement is executed as a transaction. If the statement succeeds, the transaction is committed. If the statement is cancelled or otherwise fails, the transaction is rolled back.
This behavior is built in to the engine, and is not related to management studio. See Autocommit Transactions in the docs.
There are always transactions. The only thing that changes is how those transactions are isolated from each other and that in management studio the transaction might not be defined explicitly and is auto-committed when the query finishes.