Understanding database transactions
This is an introduction to database transactions.
A database transaction delimits a set of database operations (SQL statements), that are processed as a whole.
Database operations included inside a transaction are validated or canceled as a unique operation.
The database server is in charge of data concurrency and data consistency. Data concurrency allows for the simultaneous access of the same data by many users, while data consistency gives each user a consistent view of the database.
Without adequate concurrency and consistency control, data can be changed improperly, compromising integrity of your database. If you want to write applications that can work with different kinds of database servers, you must adapt the program logic to the behavior of the database servers, regarding concurrency and consistency management. This requires good knowledge of multiuser database application programming, transactions, locking mechanisms, isolation levels, and wait mode. If you are not familiar with these concepts, carefully read the documentation of each database server that covers this subject.
Usually, database servers set exclusive locks on rows that
are modified or deleted inside a transaction. These locks
are held until the end of the transaction to control concurrent
access to that data. Some database servers implement row versioning
(before modifying a row, the server makes a copy of the original
row). This technique allows readers to see a consistent copy
of the rows that are updated during a transaction not yet
committed. When the isolation level is high (REPEATABLE READ) or when
using a SELECT FOR UPDATE
statement,
the database server sets shared locks on fetched
rows, to prevent other users from changing the rows fetched by the
reader. These locks are held until the end of the transaction.
Some database servers allow read locks to be held regardless
of the transactions (WITH HOLD
cursor option),
but this is not a standard.
Programs accessing the database can change transaction parameters such as the isolation level or lock wait mode. To write portable applications, you must use a configuration that produces the same behavior on every database engine.
The recommended programming pattern regarding transactions is the following:
- The database must support transactions; this is usually the case.
- Transactions must be as short as possible (a few seconds).
- The isolation level must be at least
COMMITTED READ
. - The wait mode for locks must be
WAIT
orWAIT n
(lock timeout).
To write portable SQL applications, programmers use the BEGIN WORK
, COMMIT WORK
and ROLLBACK WORK
instructions
described in this section to delimit transaction blocks and define concurrency parameters with SET ISOLATION
and SET LOCK MODE
. These
instructions are part of the language syntax. At runtime, the database driver generates the
appropriate SQL commands to be used with the target database server. This allows you to use the same
source code for different kinds of database servers.
If you initiate a transaction with a BEGIN WORK
statement,
you must issue a COMMIT WORK
at the end
of the transaction. If one of the SQL statement fails in
the transaction, you typically issue a ROLLBACK WORK
to
force the database server to cancel any modifications that
the transaction made to the database. If you do not issue
a BEGIN WORK
statement to start a transaction, each
statement executes within its own transaction. These single-statement
transactions do not require either a BEGIN WORK
statement
or a COMMIT WORK
statement.
Recent database engines support transaction savepoints, which allows you to set markers in the
current transaction, in order to rollback to a specific point without
canceling the complete transaction. The transaction savepoint instructions
SAVEPOINT
, ROLLBACK TO
SAVEPOINT
and RELEASE
SAVEPOINT
are part of the language syntax
and can be directly used in the code.
Some database servers do not support a Data Definition Language (DDL) statements (like
CREATE TABLE
) inside transactions, and some
automatically commit the transaction when such a statement is executed.
Therefore, it is strongly recommended that you avoid DDL statements inside
transactions.
A transaction that processes many rows can exceed the limits that your operating system or the database server configuration imposes on the maximum number of simultaneous locks. Include a limited number of SQL operations in a transaction blocks.
When a program is using several database connections, and if transactions are not
terminated before switching to another connection (SET CONNECTION
), it
is mandatory to use the WITH CONCURRENT TRANSACTION
option in the
CONNECT
instruction.