Download presentation
Presentation is loading. Please wait.
1
Transaction Concurrency Control and Locking
(examples on Informix Dynamic Server)
2
Objectives Understand the need for Concurrency Control mechanisms.
Understand locks and types of locks. Understand how locking affects performance Understand isolation levels. Understand the criteria to tune the locking: the different concurrency controls. the Lock granularity/mode on a table. the Lock Wait Mode/Time of a session/transaction. the Isolation Level of a session/transaction. Identify Informix configuration parameters that affect locking. Identify potential locking issues, including dirty reads, phantom reads, non-repeatable reads, and deadlocks.
3
Transactions – Review A transaction is a program (sequence of statements) that takes a database from one consistent state to another. Transactions have the ACID properties: A – Atomicity The operation sequence is either executed completely or not at all. C – Consistency The operation sequence takes the database from any consistent state to another consistent state (correct, integrity). I – Isolation Intermediate states of transactions are not visible to other transactions (equivalence to each user feeling they are alone using the database – as in single user mode). D – Durability Completed transactions are not lost due to hardware or software failures. Atomicity - Atomicity requires that database modifications must follow an "all or nothing" rule. Each transaction is said to be atomic. If one part of the transaction fails, the entire transaction fails and the database state is left unchanged. An atomic transfer cannot be subdivided and must be processed in its entirety or not at all. Atomicity means that users do not have to worry about the effect of incomplete transactions. Consistency - This ensures that any transaction the database performs will take it from one consistent state to another. Only valid data will be written to the database. The consistency property does not say how the DBMS should handle an inconsistency other than ensure the database is clean at the end of the transaction. If, for some reason, a transaction is executed that violates the database’s consistency rules, the entire transaction could be rolled back to the pre-transactional state - or it would be equally valid for the DBMS to take some patch-up action to get the database in a consistent state. Isolation - This refers to the requirement that other operations cannot access data that has been modified during an uncompleted transaction. The question of isolation occurs in the case of concurrent transactions (multiple transactions occurring at the same time). Each transaction must remain unaware of other concurrently executing transactions, except that one transaction may be forced to wait for the completion of another transaction that has modified data that the waiting transaction requires. Durability - This is the ability of the DBMS to recover the committed transaction updates against any kind of system failure. Durability guarantees that once the user has been notified of a transaction's success the transaction will not be lost, the transaction's data changes will survive system failure, and that all integrity constraints have been satisfied, so the DBMS won't need to reverse the transaction. A transaction is deemed committed only after it is entered in the log.
4
Transactions – Isolation
Isolation means that: Multiple transactions running at the same time do not impact each other’s execution. Each user has the impression that he/she has exclusive access for the entire transaction: All other transactions that happen at the same time should appear either as before or after it. Like in a “Serial” schedule of transactions. Isolation level defines how deep transactions isolate from one another: Dirty read / Read Uncommitted Last committed read (Optimistic) Committed read Cursor stability Serializable Repeatable read If DBMS provides concurrency control support for transactions, users/programmers do not need to worry that there are other transactions running at the same time or not. The type of isolation can affect overall performance because it affects concurrency. Before you execute a SELECT statement, you can set the isolation level with the SET ISOLATION statement, which is an Informix® extension to the ANSI SQL-92 standard, or with the ANSI/ISO-compliant SET TRANSACTION. The main differences between the two statements are that SET ISOLATION has an additional isolation level, Cursor Stability, and SET TRANSACTION cannot be executed more than once in a transaction as SET ISOLATION can. The SET ISOLATION statement is an Informix extension to the ANSI SQL-92 standard. The SET ISOLATION statement can change the enduring isolation level for the session * Dirty Read isolation - The Dirty Read isolation (or ANSI Read Uncommitted) level does not place any locks on any rows fetched during a SELECT statement. Dirty Read isolation is appropriate for static tables that are used for queries. * Committed Read isolation - A reader with the Committed Read isolation (or ANSI Read Committed) isolation level checks for locks before returning a row. By checking for locks, the reader cannot return any uncommitted rows. * Cursor Stability isolation - A reader with Cursor Stability isolation acquires a shared lock on the row that is currently fetched. This action assures that no other user can update the row until the user fetches a new row. * Repeatable Read isolation - Repeatable Read isolation (ANSI Serializable and ANSI Repeatable Read) is the strictest isolation level. With Repeatable Read, the database server locks all rows examined (not just fetched) for the duration of the transaction.
5
Need for Concurrency Control
Isolation (+ Consistency) => Concurrency Control Multiple transactions may want to access and modify the same resources. Whenever multiple processes share resources there is need to schedule the access. Concurrency control: Takes care that transactions access database items (database, table, page, row, index key) such that the meaningful results are produced. Produces a schedule of database operations from transactions running concurrently so the order of operations for each particular transaction is preserved. Concurrency and locks If your database is contained in a single-user workstation, without a network connecting it to other computers, concurrency is unimportant. In all other cases, you must allow for the possibility that, while your program is modifying data, another program is also reading or modifying the same data. Concurrency involves two or more independent uses of the same data at the same time. A high level of concurrency is crucial to good performance in a multiuser database system. Unless controls exist on the use of data, however, concurrency can lead to a variety of negative effects. Programs could read obsolete data; modifications could be lost even though it seems they were entered successfully. To prevent errors of this kind, the database server imposes a system of locks. A lock is a claim, or reservation, that a program can place on a piece of data. The database server guarantees that, as long as the data is locked, no other program can modify it. When another program requests the data, the database server either makes the program wait or turns it back with an error. To control the effect that locks have on your data access, use a combination of SQL statements: SET LOCK MODE and either SET ISOLATION or SET TRANSACTION. You can understand the details of these statements after reading a discussion on the use of cursors from within programs.
6
Transaction Schedule – By Example
Assume that Transaction T1 has operations O1 O2 O3 Assume that Transaction T2 has operations P1 P2 P3 O1O2P1O3P2P3 is a schedule. O1P1O3P2P3O2 is not a schedule Order is not preserved operation O3 must be executed after O2 within T2 Operation sequencing within a transaction MUST be preserved even if operations which are elements of one transaction are interspersed with operations which are elements of another transaction.
7
Serial Schedule Schedule is serial if all operations from one transaction are completed prior to beginning of another transaction. Each serial schedule is considered correct since one transaction is independent of the other transactions: There is no overlapping of transactions. Serial scheduling of the operations of each transaction is the simplest way of managing database transactions but this will impact negatively on performance.
8
Serial Schedule – Examples and Main Problem
In the example on the right: Transactions T1 and T2 update totally different items of the database (X,Y). Hence, T1 and T2 could have been executed concurrently (“in parallel”). Serial schedules are always correct but do not use computer resources on optimal way (for concurrency and performance). An example of the performance issues serial transaction handling causes.
9
How To Improve Efficiency? Non-serial schedules
Allow transactions to occur at the same time (concurrently). Operations of one transaction can be executed before another transaction is committed. Schedules where transactions occur concurrently are called non-serial or concurrent schedules. Concurrent scheduling helps avoid the performance constraints caused by serial processing of transactions.
10
Non-Serial Schedule – Example and New Problems
If operations are not “meaningfully” ordered, we can get unexpected results. Typical problems with schedules: Dirty read. Non-repeatable read. Phantom read. Concurrent scheduling helps avoid the performance constraints caused by serial processing of transactions but it does create a different set of problems to do with the integrity of reading data in one transaction which might have been affected by operations within another transaction.
11
Dirty Read – Problem and Example
A Dirty Read occurs because transaction T2 sees the uncommitted results of transaction T1: Transaction T1 reads an item and updates it. Transaction T2 reads updated item. Transaction T1 might abort in the future (and its update would be annulled) In meantime, transaction T2 proceeds with the item that now has incorrect / uncommitted value. Expected (good) behavior if the transactions were serialized: Once T1 is aborted, T2 will still use the old (valid, non-updated) value of the item. The Dirty Read isolation (or ANSI Read Uncommitted) level does not place any locks on any rows fetched during a SELECT statement. Dirty Read isolation is appropriate for static tables that are used for queries. Use Dirty Read isolation with care if update activity occurs at the same time. With Dirty Read, the reader can read a row that has not been committed to the database and might be eliminated or changed during a rollback. For example, consider the following scenario: User 1 starts a transaction. User 1 inserts row A. User 2 reads row A. User 1 rolls back row A. User 2 reads row A, which user 1 rolls back seconds later. In effect, user 2 read a row that was never committed to the database. Uncommitted data that is rolled back can be a problem in applications. Because the database server does not check or place any locks for queries, Dirty Read isolation offers the best performance of all isolation levels. However, because of potential problems with uncommitted data that is rolled back, use Dirty Read isolation with care. Because problems with uncommitted data that is rolled back are an issue only with transactions, databases that do not have transaction (and hence do not allow transactions) use Dirty Read as a default isolation level. In fact, Dirty Read is the only isolation level allowed for databases that do not have transaction logging.
12
Non-Repeatable Read – Problem and Example
A Non-repeatable Read occurs if transaction T1 retrieves a different result from the each read: Transaction T1 reads an item. Transaction T2 reads and updates the same item. Transaction T1 reads the same item again, but now it has a new, modified value. Expected (good) behavior if the transactions were serialized: If a transaction only reads (and does not modify) the item, each time the item is read, the same value will be obtained. Non-repeatable reads may occur when read locks are not acquired when performing a SELECT, or when the acquired locks on affected rows are released as soon as the SELECT operation is performed. Under the multiversion concurrency control method, non-repeatable reads may occur when the requirement that a transaction affected by a commit conflict must roll back is relaxed. There are two basic strategies used to prevent non-repeatable reads. The first is to delay the execution of Transaction 2 until Transaction 1 has committed or rolled back. This method is used when locking is used, and produces the serial schedule T1, T2. A serial schedule does not exhibit non-repeatable reads behaviour. In the other strategy, as used in multiversion concurrency control, Transaction 2 is permitted to commit first, which provides for better concurrency. However, Transaction 1, which commenced prior to Transaction 2, must continue to operate on a past version of the database — a snapshot of the moment it was started. When Transaction 1 eventually tries to commit, the DBMS checks if the result of committing Transaction 1 would be equivalent to the schedule T1, T2. If it is, then Transaction 1 can proceed. If it cannot be seen to be equivalent, however, Transaction 1 must roll back with a serialization failure.
13
Phantom Read – Problem and Example
A Phantom Read occurs if transaction T1 obtains a different result from each Select for the same criteria: Transaction T1 executes search on certain criteria and retrieve m items from a table. Transaction T2 inserts another item that would match the search criteria. Transaction T1 again executes search and now retrieves m+1 items from the table. Expected (good) behavior if the transactions were serialized: The first and the second search within the same transaction will give the same result. A phantom read occurs when, in the course of a transaction, two identical queries are executed, and the collection of rows returned by the second query is different from the first. This can occur when range locks are not acquired on performing a SELECT ... WHERE operation. The phantom reads anomaly is a special case of Non-repeatable reads when Transaction 1 repeats a ranged SELECT ... WHERE query and, in the middle of both operations, Transaction 2 creates (i.e. INSERT) new rows (in the target table) fulfilling that WHERE clause. Note that Transaction 1 executed the same query twice. If the highest level of isolation were maintained, the same set of rows should be returned both times, and indeed that is what is mandated to occur in a database operating at the SQL SERIALIZABLE isolation level. However, at the lesser isolation levels, a different set of rows may be returned the second time. In the SERIALIZABLE isolation mode, Query 1 would result in all records with age in the range 10 to 30 being locked, thus Query 2 would block until the first transaction was committed. In REPEATABLE READ mode, the range would not be locked, allowing the record to be inserted and the second execution of Query 1 to include the new row in its results.
14
Introducing Locking Locking is very important in a multi-user DBMS.
Locking allows one user to work with a data item without another user changing the data item's value. Locking is necessary for maintaining data integrity while concurrent users access database information. A lock is a software mechanism that you can set to prevent others from using a resource. You can place a lock on a single row or key, a page of data or index keys, a whole table, or an entire database. The maximum number of rows or pages locked in a single transaction is controlled by the total number of locks configured. The number of tables in which those rows or pages are locked is not explicitly controlled. * Locking granularity - The level and type of information that the lock protects is called locking granularity. Locking granularity affects performance. * Row and key locks - Row and key locks generally provide the best overall performance when you are updating a relatively small number of rows, because they increase concurrency. However, the database server incurs some overhead in obtaining a lock. For an operation that changes a large number of rows, obtaining one lock per row might not be cost effective. * Page locks - Page locking is the default mode when you create a table without the LOCK MODE clause. With page locking, instead of locking only the row, the database server locks the entire page that contains the row. If you update several rows on the same page, the database server uses only one lock for the page. * Table locks - In a data warehouse environment, it might be more appropriate for queries to acquire locks of larger granularity. For example, if a query accesses most of the rows in a table, its efficiency increases if it acquires a smaller number of table locks instead of many page or row locks. * Database locks - You can place a lock on the entire database when you open the database with the DATABASE statement. A database lock prevents read or update access by anyone but the current user.
15
Locks A lock is implemented as a variable associated to a data item.
Can be placed explicitly by the program, or implicitly by the DBMS. Lock describes status of an item with respect to operations that can be performed on the item. Lock types Shared locks: Multiple users can read an item at the same time. Exclusive locks: Only one user can read an item at the same time. Promotable (Update) lock: A lock can upgrade (from shared to exclusive) or downgrade (vice versa). Intent lock: Placed at the table level, to indicate a cursor is working on the rows of the table. To ensure data consistency and integrity in a multi-user (concurrent access) environment, a database server must place locks on data being modified. Shared - A shared lock reserves its object for reading only. It prevents the object from changing while the lock remains. More than one program can place a shared lock on the same object. More than one object can read the record while it is locked in shared mode. Exclusive - An exclusive lock reserves its object for the use of a single program. This lock is used when the program intends to change the object. You cannot place an exclusive lock where any other kind of lock exists. After you place an exclusive lock, you cannot place another lock on the same object. Promotable/Update - A promotable (or update) lock establishes the intent to update. You can only place it where no other promotable or exclusive lock exists. You can place promotable locks on records that already have shared locks. When the program is about to change the locked object, you can promote the promotable lock to an exclusive lock, but only if no other locks, including shared locks, are on the record at the time the lock would change from promotable to exclusive. If a shared lock was on the record when the promotable lock was set, you must drop the shared lock before the promotable lock can be promoted to an exclusive lock.
16
Lock types (1) Share lock (lock-S): Exclusive lock (lock-X):
Share locks can be placed on objects that do not have an exclusive lock already placed on them. Prevents others from updating the data. But still, others can read the data (others can place S-locks on it). More than one share lock can be placed on the same object at the same time. Exclusive lock (lock-X): Exclusive locks can only be placed on rows that do not have any other kind of lock (not even S-lock) on it. Once an exclusive lock is placed on a row, no other locks (not even S-locks) can be placed on the same row anymore. Prevents others from reading or updating the data. Shared locks prevent other processes from updating the locked object. Other users maintain read access to the object. Multiple share locks can be placed on a single object. Exclusive locks are automatically placed by the database server on any object actively being modified. Exclusive locks prevent all reads except dirty reads. A DBA or user can also explicitly request an exclusive lock on a database or table to perform administrative or batch operations.
17
Lock types (2) Update lock (lock-U): Intent lock (lock-IX or IS):
Used in Update Cursors. Update locks are created by cursors that have the ‘for update’ extension specified and can only be placed on a row that doesn’t already have an exclusive or update lock on it. The update lock is converted to an exclusive lock as soon as the row is actually updated. Intent lock (lock-IX or IS): Intent locks are automatically set by Informix. If a row in a table is updated, an exclusive lock is placed on the row and an intent-exclusive lock is placed on the table. This ensures that no other session could place a share or exclusive lock on the table as long as an individual row is locked exclusively. Promotable or update locks are placed on objects that are retrieved for update but are not yet being updated. They prevent other users from acquiring exclusive or promotable locks on the object. As an example, when you open a cursor with the FOR UPDATE clause, the database server acquires an update lock on each row fetched. The lock is promoted to an exclusive lock when the UPDATE WHERE CURRENT statement is executed. Intent locks are automatically set by Informix. If a row in a table is updated, an exclusive lock is placed on the row and an intent-exclusive lock is placed on the table. This ensures that no other session could place a share or exclusive lock on the table as long as an individual row is locked exclusively.
18
Lock Compatibility Matrix
If the item already has a lock of type… Where: S = Shared Lock X = Exclusive Lock Can I place a lock of type…?
19
Duration of a Lock The program controls the duration of a database lock: A database lock is released when the database closes. Depending on whether the database uses transactions, table lock durations vary: If the database does not use transactions (no transaction log exists and you do not use a COMMIT WORK statement), an explicit table lock remains until it is removed by the execution of the UNLOCK TABLE statement. The duration of table, row, and index locks depends on the SQL statements used and whether transactions are in use. When you use transactions, the end of a transaction releases all table, row, page, and index locks: When a transaction ends (commits, rollbacks), all locks are released. Locks are released at the end of a transaction, whatever method is used to end the transaction (COMMIT or ROLLBACK). Locks are released when connection to the database is closed.
20
Informix Lock Granularity (lock scopes) (1)
With Informix, you can apply locks to: Entire databases Entire tables Disk pages Single rows, or Index-key values In general, the larger the scope of a lock, the more concurrency is reduced, but the simpler programming becomes. The level and type of information that the lock protects is called locking granularity. Locking granularity affects performance. When a user cannot access a row or key, the user can wait for another user to unlock the row or key. If a user locks an entire page, a higher probability exists that more users will wait for a row in the page. The ability of more than one user to access a set of rows is called concurrency. The goal of the database administrator is to increase concurrency to increase total performance without sacrificing performance for an individual user. Informix provides locking at various granularities. They are: • Database lock: A lock on the entire database • Table lock: A lock on an entire table • Page lock: A lock on an entire page of data • Row lock: A lock on a single data row • Byte lock: A lock on a row containing VARCHARs • Key lock: A lock on a single key value in an index The coarser the granularity, the more database objects will be locked by a single lock. For example, for a table that can contain four rows on a disk page, a single lock placed on a page will result in all four rows being locked. On the contrary, if a row lock is used, then only one row will be locked. As such, coarser granularity will result in lesser concurrency and thus affect performance, especially when applications tend to access the same set of rows. However, coarser granularity would also mean less number of locks needed to lock the same number of rows in some cases. For example, only one lock is required to lock the entire table.
21
Informix Lock Granularity (lock scopes) (2)
When the different lock granularities are useful / optimal? Database-level locks Useful for some administrative activities, such as imports and exports: Ex: DATABASE database_name EXCLUSIVE Table-level locks Useful and more efficient when an entire table or most of the tables rows are being updated LOCK TABLE tab1 IN EXCLUSIVE MODE LOCK TABLE tab2 IN SHARE MODE To unlock: UNLOCK TABLE tab1; Implicitly during operations like these (Completion of the statement (or end of the transaction) releases the lock): ALTER FRAGMENT ALTER INDEX ALTER TABLE CREATE INDEX (if not using ONLINE keyword) DROP INDEX (if not using ONLINE keyword) RENAME COLUMN RENAME TABLE Database locks - The act of opening a database places a shared lock on the name of the database. As long as a program has a database open, the shared lock on the name prevents any other program from dropping the database or putting an exclusive lock on it. The following statement shows how you might lock an entire database exclusively: DATABASE database_one EXCLUSIVE This statement succeeds if no other program has opened that database. After the lock is placed, no other program can open the database, even for reading, because its attempt to place a shared lock on the database name fails. A database lock is released only when the database closes. That action can be performed explicitly with the DISCONNECT or CLOSE DATABASE statements or implicitly by executing another DATABASE statement. Because locking a database reduces concurrency in that database to zero, it makes programming simple; concurrent effects cannot happen. However, you should lock a database only when no other programs need access. Database locking is often used before applying massive changes to data during off-peak hours. Table locks - You can lock entire tables. In some cases, the database server performs this action automatically. You can also use the LOCK TABLE statement to lock an entire table explicitly. The LOCK TABLE statement or the database server can place the following types of table locks: Shared lock - No users can write to the table. In shared mode, the database server places one shared lock on the table, which informs other users that no updates can be performed. In addition, the database server adds locks for every row updated, deleted, or inserted. Exclusive lock - No other users can read from or write to the table. In exclusive mode, the database server places only one exclusive lock on the table, no matter how many rows it updates. An exclusive table lock prevents any concurrent use of the table and, therefore, can have a serious effect on performance if many other programs are contending for the use of the table. However, when you need to update most of the rows in a table, place an exclusive lock on the table.
22
Informix Lock Granularity (lock scopes) (3)
When the different lock granularities occur? Page locking Provides the optimum in lock efficiency when rows are being accessed and modified in physical order. If you want to move the lock mode of a table from ROW to PAGE: ALTER TABLE tab1 LOCK MODE PAGE; Default locking mode for Informix tables. Default lock mode for all new tables can be set in Informix configuration: (ONCONFIG) file, with parameter DEF_TABLE_LOCKMODE. Ex: DEF_TABLE_LOCKMODE ROW Row locks Deliver the highest degree of concurrent access and are most useful for OLTP activity. OLTP Tables should and must have lock mode ROW: CREATE TABLE tab1 (col1...) LOCK MODE ROW; ALTER TABLE tab1 LOCK MODE (ROW); Key locking Is automatic in conjunction with row-level locking to ensure the same optimal level of concurrency during index updates. Page locks - The database server stores data in units called disk pages. A disk page contains one or more rows. In some cases, it is better to lock a disk page than to lock individual rows on it. For example, with operations that require changing a large number of rows, you might choose page-level locking because row-level locking (one lock per row) might not be cost effective. If you do not specify a LOCK MODE clause when you create a table, the default behaviour for the database server is page-level locking. With page locking, the database server locks the entire page that contains the row. If you update several rows that are stored on the same page, the database server uses only one lock for the page. Row and key locks - You can lock one row of a table. A program can lock one row or a selection of rows while other programs continue to work on other rows of the same table. Row and key locking are not the default behaviours. You must specify row-level locking when you create the table. The following example creates a table with row-level locking: CREATE TABLE tab1 (col1... ) LOCK MODE ROW; If you specify a LOCK MODE clause when you create a table, you can later change the lock mode with the ALTER TABLE statement. The following statement changes the lock mode on the reservations table to page-level locking: ALTER TABLE tab1 LOCK MODE PAGE In certain cases, the database server has to lock a row that does not exist. To do this, the database server places a lock on an index-key value. Key locks are used identically to row locks. When the table uses row locking, key locks are implemented as locks on imaginary rows. When the table uses page locking, a key lock is placed on the index page that contains the key or that would contain the key if it existed.
23
Informix Lock Granularity (lock scopes) (4)
What is the type of data object (item) that is locked (secured)? More Concurrency Less Deadlocks Larger overhead to maintain locks More Difficult to implement Index key Row Page Table Database Because a lock serializes access to one piece of data, it reduces concurrency; any other programs that want access to that data must wait. The database server can place a lock on a single row, a disk page, a whole table, or an entire database. (A disk page might hold multiple rows and a row might require multiple disk pages.) The more locks it places and the larger the objects it locks, the more concurrency is reduced. The fewer the locks and the smaller the locked objects, the greater concurrency and performance can be. The two following points need to be balanced to achieve optimal SQL operation: * Place all the locks necessary to ensure data integrity. * Lock the fewest, smallest pieces of data possible consistent with the preceding goal.
24
Which Granularity Level is Optimal?
Depends on the character of transactions. Row and key locks generally provide the best performance overall when you update a relatively small number of rows because they increase concurrency: However, the database server has some overhead in obtaining a lock. If a typical transaction accesses a small number of records, use granularity on row (record) level. If transactions frequently access the whole table (e.g., update all salaries, etc), set coarse granularity (on the page or the table level): For massive updates on a table, lock the table in exclusive mode. Self explanatory.
25
Which Granularity Level is Optimal?
For massive updates in many tables or the whole database, lock the database in exclusive mode. Informix’s default lock granularity (lock mode) on tables is Page: ALTER TABLE statement can change the locking mode from PAGE to ROW ALTER TABLE table_name LOCK MODE (ROW); New default can be set with ONCONFIG parameter DEF_TABLE_LOCKMODE oncheck –pt dbname:tablename can be used to see table’s lock mode.
26
Isolation Levels of Transactions / Sessions
In SQL we may specify what properties a transaction or a session should satisfy: What kind of data would like to read? Dirty, committed, last committed, etc. Setting the Isolation Level of a session/transaction, we may prevent some (or all) the problems we saw here, to occur. It is left on DBMS to ensure that the specified “level of isolation” is actually accomplished. The number and duration of locks placed on data during a SELECT statement depend on the level of isolation that the user sets. The type of isolation can affect overall performance because it affects concurrency. Before you execute a SELECT statement, you can set the isolation level with the SET ISOLATION statement, which is an Informix® extension to the ANSI SQL-92 standard, or with the ANSI/ISO-compliant SET TRANSACTION. The main differences between the two statements are that SET ISOLATION has an additional isolation level, Cursor Stability, and SET TRANSACTION cannot be executed more than once in a transaction as SET ISOLATION can. The SET ISOLATION statement is an Informix extension to the ANSI SQL-92 standard. The SET ISOLATION statement can change the enduring isolation level for the session * Dirty Read isolation - The Dirty Read isolation (or ANSI Read Uncommitted) level does not place any locks on any rows fetched during a SELECT statement. Dirty Read isolation is appropriate for static tables that are used for queries. * Committed Read isolation - A reader with the Committed Read isolation (or ANSI Read Committed) isolation level checks for locks before returning a row. By checking for locks, the reader cannot return any uncommitted rows. * Cursor Stability isolation - A reader with Cursor Stability isolation acquires a shared lock on the row that is currently fetched. This action assures that no other user can update the row until the user fetches a new row. * Repeatable Read isolation - Repeatable Read isolation (ANSI Serializable and ANSI Repeatable Read) is the strictest isolation level. With Repeatable Read, the database server locks all rows examined (not just fetched) for the duration of the transaction.
27
Informix isolation levels: Dirty Read (1)
ANSI: SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; Informix: SET ISOLATION TO DIRTY READ; With this isolation level used at the session/transaction, the database server does not place any locks or check for existing locks when resolving your query. Dirty-read isolation is the only isolation level available for non-logging databases. The Dirty Read isolation (or ANSI Read Uncommitted) level does not place any locks on any rows fetched during a SELECT statement. Dirty Read isolation is appropriate for static tables that are used for queries. Because problems with uncommitted data that is rolled back are an issue only with transactions, databases that do not have transaction (and hence do not allow transactions) use Dirty Read as a default isolation level. In fact, Dirty Read is the only isolation level allowed for databases that do not have transaction logging. When the isolation level is read uncommitted or dirty read, the database server does not place any locks or check for existing locks when resolving your query. During retrieval, you can look at any row, even those that contain uncommitted changes. Dirty-read isolation makes it possible for your query to retrieve phantom rows. A phantom row is a row that a transaction inserts, but the transaction is rolled back rather than committed. Although the phantom row is never committed to the database and therefore never truly exists in the database, it is visible to any process using dirty-read isolation.
28
Informix isolation levels: Dirty Read (2)
Dirty-read isolation makes it possible for your query to retrieve phantom rows. Dirty-read isolation is the only isolation level available for non-logging databases. Dirty-read isolation can be useful when: The table is static (no updates, read-only tables). 100% is not as important as speed and freedom from contention. You cannot wait for locks to be released. Because the database server does not check or place any locks for queries, Dirty Read isolation offers the best performance of all isolation levels. However, because of potential problems with uncommitted data that is rolled back, use Dirty Read isolation with care. Use Dirty Read isolation with care if update activity occurs at the same time. With Dirty Read, the reader can read a row that has not been committed to the database and might be eliminated or changed during a rollback. For example, consider the following scenario: User 1 starts a transaction. User 1 inserts row A. User 2 reads row A. User 1 rolls back row A. User 2 reads row A, which user 1 rolls back seconds later. In effect, user 2 read a row that was never committed to the database. Uncommitted data that is rolled back can be a problem in applications.
29
Informix isolation levels: Committed Read (3)
ANSI: SET TRANSACTION ISOLATION LEVEL READ COMMITTED; Informix: SET ISOLATION TO COMMITTED READ; Default Isolation Mode in logged non-ANSI databases. Ensures that all rows read are committed to the database: You will not see any phantom rows or dirty data. You know the current row was committed, at least when it is read. After a process reads the row, however, other processes can change it. Queries in logged databases default to ANSI read-committed isolation. Read-committed isolation is synonymous with the IBM Informix committed-read isolation. Committed Read is the default isolation level for databases with logging if the log mode is not ANSI-compliant. For databases created with a logging mode that is not ANSI-compliant, Committed Read is an appropriate isolation level for most activities. For ANSI-compliant databases, Repeatable Read is the default isolation level.
30
Informix isolation levels: Committed Read (4)
To perform a committed read, the DB server attempts to acquire a shared lock on a row before trying to read it: It does not place the lock without checking whether it can acquire the lock or not. If it can, it is guaranteed that the row exists and is not being updated by another process while it is being read. Remember, a shared lock cannot be acquired on a row that is locked exclusively, which is always the case when a row is being updated. Committed reads can be useful for: Lookups Queries Reports that yield general information. In the Committed Read isolation level, locks held by other sessions can cause SQL operations to fail if the current session cannot acquire a lock or if the database server detects a deadlock. (A deadlock occurs when two users hold locks, and each user wants to acquire a lock that the other user owns.) The LAST COMMITTED keyword option to the SET ISOLATION COMMITTED READ statement of SQL reduces the risk of locking conflicts by instructing the server to return the most recently committed version of the rows, even if another concurrent session holds an exclusive lock. You can use the LAST COMMITTED keyword option for B-tree and functional indexes, tables that support transaction logging, and tables that do not have page-level locking or exclusive locks. For more information, see information about the SET ISOLATION statement in the IBM Informix Guide to SQL: Syntax.
31
Informix isolation levels: Cursor Stability (5)
Not available in ANSI databases. Informix: SET ISOLATION TO CURSOR STABILITY; With CURSOR STABILITY, a shared lock is acquired on each row as it is read by a cursor: This shared lock is held until the next row is retrieved. If data is retrieved by using a cursor, the shared lock is held until the next FETCH is executed. A reader with Cursor Stability isolation acquires a shared lock on the row that is currently fetched. This action assures that no other user can update the row until the user fetches a new row. In the example below, at a row fetch the database server releases the lock on the previous row and places a lock on the row being fetched. At close the cursor, the server releases the lock on the last row. set isolation to cursor stability declare cursor for SELECT * FROM customer open the cursor while there are more rows fetch a row do work end while close the cursor If you do not use a cursor to fetch data, Cursor Stability isolation behaves in the same way as Committed Read. No locks are actually placed.
32
Informix isolation levels: Cursor Stability (6)
Not only can you look at committed rows, but you are assured the row will continue to exist while you are looking at it: No other process (UPDATE or DELETE) can change that row while you are looking at it. Once you move to the next row, the lock is released and the value can change. You can use SELECT statements that uses an isolation level of CURSOR STABILITY for: Lookups. Queries. Reports yielding operational data. With CURSOR STABILITY, not only can you look at committed rows, but you are assured the row will continue to exist while you are looking at it. No other process (UPDATE or DELETE) can change that row while you are looking at it. When Cursor Stability is in effect, IBM Informix places a lock on the latest row fetched. It places a shared lock for an ordinary cursor or a promotable lock for an update cursor. Only one row is locked at a time; that is, each time a row is fetched, the lock on the previous row is released (unless that row is updated, in which case the lock holds until the end of the transaction). Because Cursor Stability locks only one row at a time, it restricts concurrency less than a table lock or database lock. Cursor Stability ensures that a row does not change while the program examines it. Such row stability is important when the program updates some other table based on the data it reads from the row. Because of Cursor Stability, the program is assured that the update is based on current information. It prevents the use of stale data.
33
Informix isolation levels: Repeatable Read (7)
ANSI: SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; Informix: SET ISOLATION TO REPEATABLE READ; Default isolation level in ANSI databases. The database server places a shared lock on all the rows that the database server examines for a query: All these locks are held until the transaction is committed. Other users can read the data, but cannot modify it in any way. Repeatable Read isolation (ANSI Serializable and ANSI Repeatable Read) is the strictest isolation level. With Repeatable Read, the database server locks all rows examined (not just fetched) for the duration of the transaction. The example below shows when the database server places and releases locks for a repeatable read. At a row fetch, the server places a lock on the row being fetched and on every row it examines in order to retrieve this row. At the cursor close, the server releases the lock on the last row. set isolation to repeatable read begin work declare cursor for SELECT * FROM customer open the cursor while there are more rows fetch a row do work end while close the cursor commit work When you use Committed Read or Cursor Stability, the previous scenario can occur. However, it cannot occur with Repeatable Read. The original application holds a read lock on each account that it examines until the end of the transaction, so the attempt by the second application to change the first account fails (or waits, depending upon SET LOCK MODE).
34
Informix isolation levels: Repeatable Read (8)
You are assured the row will continue to exist not only while you are looking at it, but also when you reread it later within the same transaction. Repeatable reads are useful when you must treat all rows read as a unit or you need to guarantee that a value does not change. For example: Critical, aggregate arithmetic (as in account balancing). Coordinated lookups from several tables (as in reservation systems). Repeatable Read is useful during any processing in which multiple rows are examined, but none must change during the transaction. For example, suppose an application must check the account balance of three accounts that belong to one person. The application gets the balance of the first account and then the second. But, at the same time, another application begins a transaction that debits the third account and credits the first account. By the time that the original application obtains the account balance of the third account, it has been debited. However, the original application did not record the debit of the first account. When you use Committed Read or Cursor Stability, the previous scenario can occur. However, it cannot occur with Repeatable Read. The original application holds a read lock on each account that it examines until the end of the transaction, so the attempt by the second application to change the first account fails (or waits, depending upon SET LOCK MODE). Because even examined rows are locked, if the database server reads the table sequentially, a large number of rows unrelated to the query result can be locked. For this reason, use Repeatable Read isolation for tables when the database server can use an index to access a table. If an index exists and the optimizer chooses a sequential scan instead, you can use directives to force use of the index. However, forcing a change in the query path might negatively affect query performance.
35
Informix isolation levels: Last Committed Read (9)
The Problem with Committed Read: Avoiding Locked Rows: Updated rows cannot be read until the change is committed unless they use dirty reads. Applications may perform poorly if they wait on updated rows to commit. Applications can use dirty reads but may get unexpected results. Deadlocks may occur which waste a significant amount of time. Use the LAST COMMITTED keyword option of the Committed Read isolation level to reduce the risk of exclusive row-level locks held by other sessions either causing applications to fail with locking errors, or preventing applications from reading a locked row until after a concurrent transaction is committed or rolled back. In contexts where an application attempts to read a row on which another session holds an exclusive lock, these keywords instruct the database server to return the most recently committed version of the row, rather than wait for the lock to be released. This feature also takes effect implicitly in all user sessions that use the Dirty Read isolation level of the SET ISOLATION statement, or that use the Read Uncommitted isolation level of the ANSI/ISO-compliant SET TRANSACTION statement, under any of the following circumstances: * if the USELASTCOMMITTED configuration parameter is set to 'DIRTY READ' or to 'ALL' * if the SET ENVIRONMENT statement sets the USELASTCOMMITTED session environment variable to 'DIRTY READ' or to 'ALL'.
36
Informix isolation levels: Last Committed Read (10)
The Solution: Last Committed Read (Optimistic Locking). In Committed Read isolation level, exclusive row-level locks held by other sessions can cause SQL operations to fail when attempting to read data in the locked rows. The LAST COMMITTED keyword option to the SET ISOLATION COMMITTED READ statement reduces the risk of locking conflicts when attempting to read a table. Enabling this feature cannot eliminate the possibility of locking conflicts, but they reduce the number of scenarios in which other sessions reading the same row can cause an error. The LAST COMMITTED keywords are only effective with concurrent read operations. They cannot prevent locking conflicts or errors that can occur when concurrent sessions attempt to write to the same row. This feature has no effect on Committed Read or Dirty Read behaviour in contexts where no “last committed" version of the table is available, including these: * The database does not support transaction logging * The table was created with the LOCK MODE PAGE keywords, or has been altered to have a locking mode of PAGE * The IFX_DEF_TABLE_LOCKMODE environment variable is set to ‘PAGE' * The DEF_TABLE_LOCKMODE configuration parameter is set to ‘PAGE' * The LOCK TABLE statement has explicitly set an exclusive lock on the table * An uncommitted DDL statement has implicitly set an exclusive lock on the table * The table is a system catalog table on which an uncommitted DDL statement has implicitly set an exclusive lock * The table has columns of complex data types or of user-defined data types * The table is a RAW table The scope of LAST COMMITTED semantics is neither statement-based nor transaction-based. This isolation level has the same instant-in-time scope that the Committed Read isolation level has without the LAST COMMITTED option. For example, when a query is executed twice within a single transaction with LAST COMMITTED in effect, different results might be returned by the same query, if other DML transactions that were operating on the same data are committed in the interval between the two submissions of the query. This instantaneous nature of the semantics of Committed Read and of Committed Read Last Committed exactly implements the ANSI/ISO Read Committed isolation level.
37
Informix isolation levels: Last Committed Read (11)
Also known as Optimistic Locking, common in web-based applications E-Commerce example: Typically, websites allow you to add items into your shopping-cart using the status of the item at the time you added it, even though later on, when you are checking out or updating it, it can alert you that the price or the availability status has changed. Not available in ANSI databases. Informix: SET ISOLATION TO COMMITTED READ LAST COMMITTED Provides concurrency and throughput improvement over Committed Read. The LAST COMMITTED feature does not support reading through table-level locks. If the access plan for a query that uses the LAST COMMITTED feature encounters a table-level lock in a table or index that it needs to access, the query will return the following error codes: SQL error code: 252: Cannot get system information for table. ISAM error code: 113: ISAM error: the file is locked. USELASTCOMMITTED onconfig Configuration Parameter - to specify the isolation level for which the LAST COMMITTED feature of the COMMITTED READ isolation level is implicitly in effect. The LAST COMMITTED feature can reduce the risk of locking conflicts between concurrent transactions on tables that have exclusive row locks. The USELASTCOMMITTED configuration parameter can also enable LAST COMMITTED semantics for READ COMMITTED and READ UNCOMMITTED isolation levels of the SET TRANSACTION statement. The USELASTCOMMITTED onconfig configuration parameter only works with tables that have been created or altered to have ROW as their locking granularity. Tables created without any explicit lock mode setting will use the default setting in DEF_TABLE_LOCKMODE. If DEF_TABLE_LOCKMODE is set to PAGE, the USELASTCOMMITTED configuration parameter cannot enable access to the most recently committed data in tables on which uncommitted transactions hold exclusive locks, unless the tables were explicitly altered to have ROW level of locking granularity.
38
Informix isolation levels: Last Committed Read (12)
Returns the most recently committed version of the rows, even if another concurrent session holds an exclusive lock: It ensures that writers don’t block readers. You are trying to read the row, not update it or delete it. Can be set as default isolation level using ONCONFIG parameter: USELASTCOMMITTED. The table has been configured for row-level, NOT page-level Locking.
39
Summary Informix and ANSI Isolation Levels
Informix SQL ANSI SQL Remarks Dirty Read Read Uncommitted No locks are placed during reading data and no locks from other sessions will block this reader. set isolation to dirty read [retain update locks] set transaction isolation level read uncommitted Last Committed Read Not Available Returns the most recently committed version of the rows, even if in another concurrent session holds an exclusive lock. set isolation to committed read last committed [retain update locks] Committed Read Read Committed Checks for locks being held by other sessions but does not place a lock itself. set isolation to committed read [retain update locks] set transaction isolation level read committed Cursor Stability An update lock is placed on the current fetched row, it will be promoted to an exclusive lock as soon as an update is executed. set isolation to cursor stability [retain update locks]
40
Problems that the different Isolation Levels prevent
Less protection / isolation of the data read More Concurrency Less Deadlocks Isolation level Dirty read Can occur? Nonrepeatable read Phantom read (ANSI: Read uncommitted) Yes Last Committed Read (ANSI: Not supported) No Committed read (ANSI: Read Committed) Cursor Stability Repeatable Read (ANSI: Serializable)
41
Setting the Lock Mode of a Transaction/Session
Do not wait for lock to be released (default) If the database item is locked, it will immediately return an error code: Ex: -244: Could not do a physical-order read to fetch the next row 107: ISAM error: record is locked SET LOCK MODE TO NOT WAIT; Wait forever for lock to be released: A transaction can hang and deadlocks can occur, waiting on a resource (e.g. row, page) to be released. SET LOCK MODE TO WAIT; Wait n seconds for the lock to be released: If the lock has not been released during that time, it will return an error saying the object is locked. Ex: SET LOCK MODE TO WAIT 20; The lock mode determines what happens when your program encounters locked data. One of the following situations occurs when a program attempts to fetch or modify a locked row: * The database server immediately returns an error code in SQLCODE or SQLSTATE to the program. * The database server suspends the program until the program that placed the lock removes the lock. * The database server suspends the program for a time and then, if the lock is not removed, the database server sends an error-return code to the program. You choose among these results with the SET LOCK MODE statement. * Waiting for locks * Not waiting for locks * Limited time wait * Handle a deadlock * Handling external deadlock
42
Retain Update Locks Syntax:
SET ISOLATION TO DIRTY READ RETAIN UPDATE LOCKS; SET ISOLATION TO COMMITTED READ RETAIN UPDATE LOCKS; SET ISOLATION TO CURSOR STABILITY RETAIN UPDATE LOCKS; It only affects SELECT...FOR UPDATE statements with dirty read, committed read and cursor stability isolation levels. When the update lock is in place on a row during a FETCH of a SELECT... FOR UPDATE statement with one of the isolation levels above, it is not released at the subsequent FETCH or when the cursor is closed. If a user has the isolation level set lower than Repeatable Read, the database server releases update locks placed on rows as soon as the next row is fetched from a cursor. With this feature, you can use the RETAIN UPDATE LOCKS clause to retain an update lock until the end of a transaction when you set any of the following isolation levels: * Dirty Read * Committed Read * Cursor Stability This feature lets you avoid the overhead of Repeatable Read isolation level or workarounds such as dummy updates on a row. When the RETAIN UPDATE LOCKS feature is turned on and an update lock is implicitly placed on a row during a fetch of a SELECT...FOR UPDATE statement, the update lock is not released until the end of the transaction. With the RETAIN UPDATE LOCKS feature, only update locks are held until end of transaction, whereas the Repeatable Read isolation level holds both update locks and shared locks until end of transaction. The following example shows how to use the RETAIN UPDATE LOCKS clause when you set the isolation level to Committed Read. SET ISOLATION TO COMMITTED READ RETAIN UPDATE LOCKS To turn off the RETAIN UPDATE LOCKS feature, set the isolation level without the RETAIN UPDATE LOCKS clause. When you turn off the feature, update locks are not released directly. However, from this point on, a subsequent fetch releases the update lock of the immediately preceding fetch but not of earlier fetch operations. A close cursor releases the update lock on the current row. For more information about how to use the RETAIN UPDATE LOCKS feature when you specify an isolation level, see the IBM Informix Guide to SQL: Syntax.
43
Retain Update Locks The update lock is retained until the end of the transaction. This feature lets you avoid the overhead of the repeatable-read isolation level or workarounds, such as dummy updates on a row.
44
Deadlock A deadlock occurs if two sessions hold a lock and each session wants to acquire a lock that the other sessions already owns Example: Process A waits for process B to release resources. Process B waits for process A to release some other resources. Process A waits for B which waits for A which waits for B… So this infinite loop need be interrupted. A deadlock is automatically solved by Informix: Before granting a new lock, Informix scans the internal lock table and delivers ISAM error code 143 to the application if it detects a possible deadlock situation. For distributed transaction the maximum lock wait time is specified thru the ONCONFIG parameter DEADLOCK_TIMEOUT. This is also the time it will pass before Informix declares a deadlock has occurred. A deadlock is a situation in which a pair of programs blocks the progress of each other. Each program has a lock on some object that the other program wants to access. A deadlock arises only when all programs concerned set their lock modes to wait for locks. In some databases, when multiple users request locks on the same resources, deadlocks can occur. Deadlocks are serious problems, as they can halt a major portion of the activity in a database system. IBM Informix Dynamic Server has a built-in, sophisticated mechanism that detects potential deadlocks and prevents them from happening. To prevent local deadlocks from occurring, the database server maintains a list of locks for every user on the system. Before a lock is granted, the lock list for each user is examined. If a lock is currently held on the resource that the process requests to lock, the owner of that lock is identified and their lock list is traversed to see if waits on any locks are held by the user who wants the new lock. If so, the deadlock is detected at that point and an error message is returned to the user who requested the lock. The ISAM error code returned is: -143 ISAM error: deadlock detected
45
Informix – Total Number of Locks in the system (1)
LOCKS parameter in ONCONFIG: Specifies the initial size of the lock table that is allocated in resident memory, or the number of locks in this internal table. The lock table holds an entry for each lock. Max. configurable size of Informix lock table is: Informix 32-Bit locks Informix 64-Bit locks The lock table holds an entry for each lock. If the number of locks allocated exceeds the value of the LOCKS configuration parameter, the database server increases the size of the lock table. The lock table can be increased a maximum of 99 times. onconfig.std LOCKS parameter: * value * units Number of locks in the internal lock table * range of values 2,000 through 8,000,000 for 32-bit database servers * range of values 2,000 through 500,000,000 for 64-bit database servers * takes effect when the database server is shut down and restarted The database server increases the size of the lock table by attempting to double the lock table on each increase. However, the amount added during each increase is limited to a maximum value. For 32-bit platforms, a maximum of 100,000 locks can be added during each increase. Therefore, the total maximum locks allowed for 32-bit platforms is 8,000,000 (maximum number of starting locks) + (99 (maximum number of dynamic lock table extensions) x 100,000 (maximum number of locks added per lock table extension). For 64-bit platforms, a maximum of 1,000,000 locks can be added during each increase. Therefore, the total maximum locks allowed is 500,000,000 (maximum number of starting locks) + (99 (maximum number of dynamic lock table extensions) x 1,000,000 (maximum number of locks added per lock table extension). With the initial lock table stored in resident memory and each additional lock stored in virtual memory, locks can become a resource drain if you have a limited amount of shared memory. The amount of storage occupied by a single lock depends on the word size and operating system, and is subject to change. Currently, the amount of storage ranges from approximately 100 to 200 bytes. You can see the amount of storage required to support additional locks by restarting the server with a different value of the LOCKS configuration parameter (without making other changes), and observing the increase in memory used as shown by "onstat -g mem" for the resident pool.
46
Informix – Total Number of Locks in the system (2)
Automatic dynamic lock allocation: If while Informix is operating, the number of locks allocated exceeds the value of LOCKS, the database server increases the size of the lock table. Informix increases the size of the lock table by attempting to double the lock table on each increase. Informix automatically doubles the size of the lock table up to 15 times if the lock table becomes full Each lock table increase is limited to locks: 32-Bit: (15 x ) = 64-Bit: (15 x ) =
47
Informix – Monitoring the Locks
Monitoring isolation levels the sessions use: Use: onstat –g sql and/or onstat –g ses To see details of a session of id sid: onstat –g sql sid Monitoring the status of the user threads (waiting on locks?): Use: onstat –u Monitoring the locks being held and waited for: Use: onstat -k Monitoring the transactions and their status: Use: onstat -x
48
References IBM Informix Guide to SQL: Tutorial - Programming for a Multiuser Environment IBM Informix Dynamic Server Administration Guide: Locking Informix Dynamic Server locking, Part 1: Understand locking behavior and analyze locking conflicts in Informix Informix DBA: Informix Performance Locking and Concurrency (old but good) Informix Unleashed book – Ch 15: Managing Data with Locking
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.