Isolation property

Applies to
TIB_Transaction

Declaration
Property Isolation : TIB_Isolation;

Description
Determines the isolation level of the transaction.

These are the supported modes of isolation:


tiConcurrency - Read-Repeatable or Snapshot
tiConsistency - Forced-Repeatable or Forced Snapshot (Exclusive access)
tiCommitted - Read-Committed

I'll summarize each one's behavior.

tiConcurrency - Read-Repeatable or Snapshot

This transaction isolation is ideal for reports or exports that need to be able to work with a consistant view of the data in a way that will not block others from continuing to update the data. As long as the transaction is open you are guaranteed to get the same exact view of the data over and over again. Essentially, you are given a true SNAPSHOT of the data.

It is possible to update data from this transaction and the updates made within your own transaction context are visible. But, if another user or transaction context has any posted OR COMMITTED changes (on a per individual record basis) then this isolation level will always confront a deadlock resolution for whatever records have been altered when attempting to perform an update or delete on those records. This is because the snapshot baseline for the transaction has record versions of other transactions after it. Since these other changes are not visible to this transaction it will not allow new changes based on an older view of the database to be posted over them.

Thus, as far as locking for this isolation is concerned, any limbo or committed changes on records from another transaction context will result in a deadlock if a change is attempted on any of these records. The only way to be able to avoid the deadlocks is to close and reopen the transaction in order to establish a more recent baseline to work from.

This isolation level is not ideal for user interfaces that involve browsing of data and "pot-shot" editing of records. As users work on the data they will slowly build up locks and nobody can see each other's work once it has committed. How is the user to know when they should do a rollback or commit in order to resolve these matters? This is a bit dangerous to give the user this level of control. Plus, all of the buffered data for the datasets is closed and the user starts all over again.

This is the default isolation for explicitly defined transactions when you use an IB_TransactionXXXX component yourself from the component pallette. Otherwise, an individual internal transaction is generated for each IB_DSQL, IB_Cursor and IB_Query component that does not assign a transaction object to the IB_Transaction property .

tiConsistency - Forced-Repeatable or Forced Snapshot

This isolation is the same as above except that it also imposes the same of other transactions. It keeps a consistant view of the data and also does not allow any other transaction to alter the data. This is why I say "Forced" because it also forces that its view of the data is going to stay the same.

This isolation should ONLY be used when you know exactly what you are doing. It will cause deadlocks galore since it is a blocking transaction. This could lock up a database and keep others from making changes. Of course, if this is what you want to accomplish then go for it.

Keep in mind that there are also ways of using these isolation levels for individual tables as well. So this could become a powerful tool to put together some specialized functionality on a per table basis.

tiCommitted - Read-Committed

This is the ideal isolation for a browsing user interface because it keeps up with all committed changes in the database as they occur. Thus, the interface can be refreshed to reflect changes in the database without having to start a new transaction.

If using an IB_Query component it is even possible to refresh individual rows of a dataset or, based on a refresh of the keys of the dataset, refresh the order or inclusion (in case of deletes and inserts by other users or a change in the ORDER BY criteria) of records without having to refetch the individual records of the dataset again. When this type of refresh is performed all of the row buffers are stored aside so that when their keys are fetched from the server they are reassociated with the record buffer in memory.

This isolation should not be used to run a report or an export because the data may change in a manner that will cause the report to be skewed or inconsistent. When designing an application it is a good idea to have the users browsing on an IB_Query based dataset and then if they want to run a report take the SQL of the IB_Query and assign it to an IB_Cursor that has a different transaction isolation (tiConcurrency) and run the report. Be sure to start with a fresh transaction too. There is an excellent way to move the SQL from an IB_Query to an IB_Cursor that will even keep all of the search criteria of the IB_Query. See the method AssignSQLWithSearch() for more information.

This isolation level is the default isolation for internally defined transactions when the IB_Transaction property of an IB_DSQL, IB_Cursor or IB_Query is left undefined. This is because AutoCommit is also changed to default to true in this circumstance and when AutoCommit is true the isolation of tiCommitted is more sensible. AutoCommit does not demand the isolation be set to tiCommitted.

In InterBase it is not possible to perform a "dirty-read" in which posted and non-committed data from another transaction's context is read. Each transaction defines how it will be able to read data from the database.