What is the difference between abort and rollback in transaction management?
If you mean the commands, normally none.
From - for example - the PostgreSQL manual;
ABORT rolls back the current transaction and causes all the updates
made by the transaction to be discarded. This command is identical in
behavior to the standard SQL command ROLLBACK, and is present only for
historical reasons.
If you mean the database aborting a transaction automatically, this is usually done when there is an irrecoverable error (for example a lost connection) and is also normally done by rolling back the active transaction.
Related
I have some scripts including DDL and DML transactions that use an Informix 14 database that I want to run some tests against.
If the tests fail they will often leave the database in an inconsistent state that needs to be manually resolved before the tests can be run again.
I would like to automate this so that the tests do not require manual intervention before running the tests again.
So, is it possible to use rollback and savepoint without locking the database and run some tests on the database?
If you execute BEGIN WORK (or just BEGIN), then everything you do afterwards will be part of the same transaction until you explicitly execute COMMIT WORK (or just COMMIT) or ROLLBACK WORK (or just ROLLBACK) — or until your program exits without explicitly ending the transaction. If your program terminates unexpectedly or carelessly (without explicitly completing the transaction), the transaction will be rolled back.
The transaction will manage all the DDL and DML operations — with the sole exception of some caveats with the TRUNCATE TABLE statement. There are some restrictions on what you can do with the truncated table — basically, it cannot be modified again until the transaction completes.
Of course, this assumes your database is logged. You can't have transactional control in an unlogged database.
I have n machines writing to DB (sql server) at the exact same time (initiating a transaction). I'm setting the Isolation level to serializable. My understanding is that whichever machine's transaction gets to the DB first, gets executed and the other transactions will be blocked while this completes.
Is that correct?
It depends - are they all performing the same activities? That is, exactly the same statements executing in the same order, with no flow control?
If not, and two connections are accessing independent objects in the DB, they can run in parallel.
If there's some overlap of resources, then some progress may be made by multiple connections until one of them wants to take a lock that another already has - at which point it will wait. There is then the possibility of deadlocks.
SERIALIZABLE:
Statements cannot read data that has been modified but not yet committed by other transactions.
No other transactions can modify data that has been read by the current transaction until the current transaction completes.
Other transactions cannot insert new rows with key values that would fall in the range of keys read by any statements in the current transaction until the current transaction completes.
whichever machine's transaction gets to the DB first, gets executed and the other transactions will be blocked while this completes
No, this i incorrect. The results should be as if each transaction was executed one after another (serially, hence the isolation level name). But the engine is free to use any implementation it likes, as long as it honors the guarantees of the serializable isolation model. And some engines actually implement it pretty much as you describe it, eg. Redis Transactions (although Redis has no 'isolation level' concept).
For SQL Server the transactions will execute in parallel until they hit a lock conflict. When a conflict occurs the transaction that has the lock granted continues undisturbed, while the one that requests the lock in a conflicting mode has to wait for the lock to free (for the granted transaction to commit). Which transaction happens to be the request and which one happens to be the granted is entirely up to what is being executed. That means that it well may be the case that the second machine gets the grant first and finishes first, while the first machine waits.
For a better understanding how the locking behavior differs under serializable isolation level, see Key-Range Locking
Yes, this will be true for write operations at any isolation level: "My understanding is that whichever machine's transaction gets to the DB first, gets executed and the other transactions will be blocked while this completes."
The isolation level helps determine what happens when you READ data while this is going on. Serializable read operations will block your write operations, which might be the behavior you want.
I wonder a case. I have a project using a database (Oracle and Mssql). My project has a framework that I manage transactions.
In thread I open a database connection and start a transaction.(In transaction, there are many update and insert queries.) While code is running, somehow connection is closed. Because I have try-catch block, I catch exception and rollback transaction. BUT; if my connection is closed because some reasons, how rollback query can run on database? How can I handle this situation? If I open a new connection and rollback, does it work?
Thanks.
There is a term you should know - ACID compliancy:
Atomicity is an all-or-none proposition;
Consistency guarantees that a transaction never leaves your database in a half-finished state.
Isolation keeps transactions separated from each other until they’re finished.
Durability guarantees that the database will keep track of pending changes in such a way that the server can recover from an abnormal termination.
Concerning MySQL
In order to get this at MySQL, you have to use Transaction Safe Tables (TST). Advantages of Transaction-Safe Tables:
Safer. Even if MySQL crashes or you get hardware problems, you can get your data back, either by automatic recovery or from a backup + the transaction log.
You can combine many statements and accept these all in one go with the COMMIT command.
You can execute ROLLBACK to ignore your changes (if you are not running in auto-commit mode).
If an update fails, all your changes will be restored.
Concerning SQL Server
You should read "Transaction Behavior On Lost Connection" MSDN forum topic.
To understand better what lays behind MS SQL Server transactions, read a good article "Locks and Duration of Transactions in MS SQL Server"
Make sure you are not using any autocommit feature (I think that's enabled by default in some MySQL installations). If you do all your commits "manually", a broken connection will just result in you never committing the transaction and so it won't ever get written.
You cannot reconnect to rollback in most database systems.
SqlCE has a parameter set on the Connect String called Flush Interval. It is defined as:
The interval time (in seconds) before all committed transactions are flushed to disk. If not specified, the default value is 10.
I thought that a committed transaction, by definition, is a transaction that has been flushed to disk, specifically the database file. If a transaction is only stored in RAM then cannot the transaction be easily lost?
I thought that transactions were first written to a log file and then applied to the database file itself, so perhaps this parameter could mean the time to wait until the transaction log is applied to the database file?
I would have thought that this parameter should be 0.
UPDATE-------
Let me put my database internals hat on. As I understand it, when an application starts a transaction a start-of-transaction record is written to a database LOG, then each added, changed, or deleted record, is written to the LOG then an end-of-transaction record. A separate thread detected the end-of-transaction and moved the records from the LOG to the DATABASE. When this was complete a transaction ID was incremented to indicate that the transaction was complete. If the process crashed anywhere, when the database started it would would check the LOG to ascertain the state of the database and either finish or roll back open transactions. All of this implies that work is written to disk at all steps of the process.
If Flush Interval was the time to write from the LOG to the DATABASE then everything makes sense, but if the transaction is held in RAM not a LOG then the database cannot be ACID compliant.
With newer versions, the Commit operation is overloaded. If you call Commit with a CommitMode.Immediate parameter, the Flush-Interval setting is ignored, and changes are persisted to the file immediately. The default option is CommitMode.Deferred (in the parameter-less call) which is based on the Flush-Interval value.
Refer to my post on SQLCE Corruptions: resolving corruption in SQL Server Compact Edition database files
With older versions there were indeed corruption problems. Worst case scenario with the more recent versions is missing data.
You cannot set the parameter to zero, though. 1 is the minimum.
Lets say I open a transaction and run update queries.
BEGIN TRANSACTION
UPDATE x SET y = z WHERE w = v
The query returns successfully and the transaction stays open deliberately for a period of time before I decide to commit.
While I'm sitting on the transaction is it ever possible the MSSQL deadlock machinary would be able to preempt my open transaction that is not actually executing anything to either clear a deadlock or free resources as system memory/resource limits are reached?
I know about SET DEADLOCK_PRIORITY and have read the MSDN articles on the topic of deadlocks. Logically since I'm not actively seeking to stake claim on any additional resources I can't imagine a scenario that would trigger a sane deadlock avoidance algorithm.
Does anyone know for sure if its possible that simply holding any locks can make me a valid target? Similarly could any low resource condition trigger the killing of my SPID?
NO
For a deadlock to occur all the participants in the deadlock chain must be waiting for a resource (a lock). If your connection is idle it means it doesn't execute a request, which implies it cannot be waiting.
As for other conditions that can kill your session I can think of at least three:
administrative operations that use WITH ROLLBACK_IMMEDIATE
a mirroring failover
intentional KILL <yourspid>, perhaps as a joke by your friendly DBA
To answer your question: you can be a deadlock victim if you're not executing a query in a transaction.
It's counter-intuitive, but you can be a deadlock victim by running a SELECT statement.
It can happen if you're running a query that uses an index:
you scan indexes looking for matching rows
other process starts updating data pages
you now want to fetch data from data pages from matching rows
other process holding locks on data pages
you wait for data page locks to release
other process finished updating data pages, wants to update indexes
you are holding read locks on indexes
other process waits for index locks to release
DEADLOCK
So, strictly speaking, you can be a deadlock victim, when you're not executing a query in a transaction. The other guy wasn't executing his UPDATE statement in a transaction either.
Nobody's explicitly using a transaction, yet there's a deadlock.
Possible problems:
SQL Server only has a finite number of locks. It is possible to run out of locks.
Other resources are finite (e.g. memory, tempdb). Holding on to these resources could cause those resources to run out.
Transaction logs - the logical transaction logs cannot be freed for re-use if a transaction is open. The result could be a log that fills up. This problem could stop your process because it would halt the entire instance.
To consider:
CASCADE: DELETE may only have one table in the command, but the a CASCADE relationship may touch other tables.
Triggers: Triggers on the modified table may affect other tables.
DELETE and UPDATE commands may use the FROM clause which touch other tables. I've never seen this, but I would not rule it out.
Transactions may time out, is that what is happening.
As you have at least 1 (or more) update locks taken out and make be some read and table scan locks, you may be killed to help free up deadlocks created by other transactions. The deadlock recovery code in SQL Server is unlikely to be totally bug free and it is not normal to keep a transaction open for a long time on SQL Server. However I would not expect that to happen often.
Some system when they detach deadlock type problem, just start killing “long lived” transactions that have not done match work so as to free up locks. Just because you are not part of the deadlock loop, does not stop the system picking on you.
To understand what is going on in your case, you will have to use the Sql Server Profiler to collect all the locking and deadlock related events, as well as event about aborted connection and transactions etc. Good lack this will time some time and a good level of understanding of the profiler events you are looking at...
The detail of this sort of things are different between database vendors and versions of their database. However as it is considered bad design by most database vendors to have a transaction open for a long time, doing so tends to lead to problems and hit code paths that have not had the most testing effort.
Just because you're not in a transaction doesn't mean you're not holding locks.