views:

169

answers:

7

When working with database transactions, what are the possible conditions (if any) that would cause the final COMMIT statement in a transaction to fail, presuming that all statements within the transaction already executed without issue?


For example... let's say you have some two-phase or three-phase commit protocol where you do a bunch of statements, then wait for some master process to tell you when it is ok to finally commit the transaction:

-- <initial handshaking stuff>
START TRANSACTION;
-- <Execute a bunch of SQL statements>
-- <Inform master of readiness to commit>
-- <Time passes... background transactions happening while we wait>
-- <Receive approval to commit from master (finally!)>
COMMIT;

If your code gets to that final COMMIT statement and sends it to your DBMS, can you ever get an error (uniqueness issue, database full, etc) at that statement? What errors? Why? How do they appear? Does it vary depending on what DBMS you run?

+4  A: 

It is possible for some database engines to defer UNIQUE index constraint checking until COMMIT. Obviously if the constraint does not hold true at the time of commit then it will fail.

Ignacio Vazquez-Abrams
Really? This is what I was afraid of. Do you know of any engines in particular that do this?
Russ
It's a new feature in PostgreSQL 9.0. http://wiki.postgresql.org/wiki/What%27s_new_in_PostgreSQL_9.0#DEFERRABLE_UNIQUE_CONSTRAINTS
Ignacio Vazquez-Abrams
Oracle can defer FK constraint checking, http://infolab.stanford.edu/~ullman/fcdb/oracle/or-triggers.html
Damien_The_Unbeliever
+3  A: 

Sure.

In a multi-user environment, the COMMIT may fail because of changes by other users (e.g. your COMMIT would violate a referential constraint when applied to the now current database...).

Thomas

Thomas Weller
+3  A: 

Certainly, there could be a number of issues. The act of committing, in and of itself, must make some final, permanent entry to indicate that the transaction committed. If making that entry fails, then the transaction can't commit.

As Ignacio states, there can be deferred constraint checking (this could be any form of constraint, not just unique constraint, depending on the DBMS engine).

SQL Server Specific: flushing FILESTREAM data can be deferred until commit time. That could fail.

Damien_The_Unbeliever
+3  A: 

One very simple and often overlooked item: hardware failure. The commit can fail if the underlying server dies. This might be disk, cpu, memory, or even network related.

The transaction could fail if it never receives approval from the master (for any number of reasons).

Chris Lively
+4  A: 

COMMIT may fail. You might have had sufficent resources to log all the changes you wished to make, but lack resources to actually implement the changes.

And that's not considering other reasons it might fail:

  1. The change itself might not fit the constraints of the database.

  2. Power loss stops things from completing.

  3. The level of requested selection concurrency might disallow an update (cursors updating a modified table, for example).

  4. The commit might time out or be on a connection which times out due to starvation issues.

  5. The network connection between the client and the database may be lost.

And all the other "simple" reasons that aren't on the top of my head.

Edwin Buck
+1  A: 

No matter how wonderfully a system may be designed, there is going to be some possibility that a commit will get into a situation where it's impossible to know whether it succeeded or not. In some cases it may not matter (e.g. if a hard drive holding the database turns into a pile of slag, it may be impossible to tell whether the commit succeeded or not before that occurred but it wouldn't really matter); in others cases, however, this could be a problem. Especially with distributed database systems, if a connection failure occurs at just the right time during a commit, it will be possible for the both sides to be certain of whether the other side is expecting a commit or a rollback.

supercat
+1  A: 

If you're using two-phase commit, then no. Everything that could go wrong is done in the prepare phase.

There could still be network outage, power less, cosmic rays, etc, during the commit, but even so, the transactions will have been written to permanent storage, and if a commit has been triggered, recovery processes should carry them through.

Hopefully.

Tom Anderson