Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 50 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
50
Dung lượng
0,97 MB
Nội dung
flexible facility that was described in Section 9.4, “Savepoints and
Subtransactions.”
9.6 Locks
In order to improve overall productivity, different transactions are allowed to
overlap one another in a multi-user environment. For example, if SQL Any
-
where has processed an UPDATE and is waiting to receive the next SQL
command that is part of the same transaction, and a SELECT that is part of a
different transaction arrives in the meantime, it will try to process the SELECT
immediately. If SQLAnywhere only worked on one transaction at a time, no
one would get any work done; in reality, the database engine can switch back
and forth among hundreds of overlapping transactions in a busy environment.
The ability of SQLAnywhere to process overlapping transactions is called
concurrency, and it may conflict with two of the basic requirements of a transac
-
tion: consistency and isolation. For example, if two overlapping transactions
were allowed to update the same row, the requirement that changes made by dif
-
ferent transactions must be isolated from one another would be violated.
Another example is a transaction design that requires data to remain unchanged
between retrieval and update in order for the final result to be consistent; that
requirement would be violated by an overlapping transaction that changed the
data after the first transaction retrieved it, even if the second transaction com-
mitted its change before the first transaction performed its update.
SQL Anywhere uses locks to preserve isolation and consistency while
allowing concurrency. A lock is a piece of data stored in an internal table main-
tained by SQL Anywhere. Each lock represents a requirement that must be met
before a particular connection can proceed with its work, and logically it is
implemented as a temporary relationship between that connection and a single
row or table. While it exists, a lock serves to prevent any other connection from
performing certain operations on that table or row.
When a lock is needed by a connection in order to proceed, it is said to be
requested by that connection. If SQLAnywhere creates the lock, the request is
said to be granted, the lock is said to be acquired, and the work of that connec
-
tion can proceed. If SQLAnywhere does not create the lock because some other
conflicting lock already exists, the request is said to be blocked, the lock cannot
be acquired, and the connection cannot proceed.
Locks fall into two broad categories: short-term and long-term. A
short-term lock is only held for the duration of a single SQL statement or less,
whereas a long-term lock is held for a longer period, usually until the end of a
transaction. This chapter concentrates on the discussion of long-term locks
because short-term locks are not visible from an administrative point of view.
Unless otherwise noted, the term “lock” means “long-term lock” in this chapter.
The built-in procedure sa_locks can be used to show all the locks held at a
given point in time. Here is an example of a call:
CALL sa_locks();
The following shows what the output from sa_locks looks like; each entry rep
-
resents one or more locks associated with a particular table or row. The
connection column identifies the connection that is holding the locks, the
336 Chapter 9: Protecting
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
user_id column contains the user id that was used to make the connection, the
table_name shows which table the locks are associated with, the lock_type iden
-
tifies the different kinds of locks represented by this entry, and the lock_name
column is an internal row identifier or NULL for an sa_locks entry that is asso
-
ciated with an entire table.
connection user_id table_name lock_type lock_name
========== ======= ========== ========= =========
508116521 DBA DBA.t1 E 473
508116521 DBA DBA.t3b EPA* 4294967836
508116521 DBA DBA.t1b EPA0000 4294967834
508116521 DBA DBA.t1u EPA0001 12884902403
508116521 DBA DBA.t1n EPT 528
508116521 DBA DBA.t3 S 4294967821
508116521 DBA DBA.t1 SPA0000 1095216660986
508116521 DBA DBA.t1u SPA0001 1095216661028
508116521 DBA DBA.t3n SPT 553
508116521 DBA DBA.e4b E NULL
508116521 DBA DBA.e4 EPT NULL
508116521 DBA DBA.t2n S NULL
508116521 DBA DBA.e1b SAT NULL
508116521 DBA DBA.e3 SPAT NULL
508116521 DBA DBA.t2b SPT NULL
Here is what the various characters in the lock_type column mean for lines in
the sa_locks output that have non-NULL row identifiers in the lock_name
column:
n
“E” represents an exclusive row write lock. This kind of lock won’t be
granted if any other connection has an exclusive row write lock or a shared
row read lock on the row. Once an exclusive row write lock has been
acquired, no other connection can obtain any kind of lock on the row.
n
“S” represents a shared row read lock. This kind of lock may coexist with
other shared row read locks on the same row that have been granted to
other connections.
n
“P” represents an insert, or anti-phantom, row position lock, which reserves
the right to insert a row in the position immediately ahead of the row identi
-
fied by the lock_name column. The row position is determined in one of
three ways: with respect to the order of a particular index, with respect to
the order of a sequential table scan, or with respect to all index and sequen
-
tial orderings on the table. An exclusive row write lock or a shared read
row lock is always granted at the same time as an insert row position lock.
n
“A” represents an anti-insert, or phantom, row position lock, which pre
-
vents any other connection from inserting a row in the position immediately
ahead of the row identified by the lock_name column. The row position is
determined in the same manner as for an insert lock. An exclusive row
write lock or a shared read row lock is always granted at the same time as
an anti-insert row position lock. Also, anti-insert and insert locks may be
granted at the same time; e.g., the combinations “EPA” and “SPA” mean
that three locks associated with the same row are represented by one entry
in the sa_locks output.
n
A four-digit integer like 0000 or 0001 identifies the index used to determine
the row ordering for insert and anti-insert row position locks.
Chapter 9: Protecting
337
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
n
“T” specifies that a sequential table scan is used to determine the row
ordering for insert and anti-insert row position locks.
n
The asterisk (*) specifies that the insert and anti-insert locks apply to all
index and sequential orders.
Here is what the various characters in the lock_type column mean for lines in
the sa_locks output that have NULL values in the lock_name column:
n
“E” represents an exclusive table schema lock.
n
“S” represents a shared table schema lock.
n
“PT” represents a table contents update intent lock.
n
“AT” represents a table contents read lock.
n
“PAT” represents a combination of two table contents locks: update intent
and read.
Here are all the combinations of lock_type and lock_name from the earlier
example of sa_locks output, together with a description of the locks they repre
-
sent according to the definitions given above:
Table 9-2. lock_type and lock_name combinations
lock_type lock_name Description
E 473 Exclusive row write lock
EPA* 4294967836 Exclusive row write lock, plus insert and
anti-insert row position locks with respect to
all orders
EPA0000 4294967834 Exclusive row write lock, plus insert and
anti-insert row position locks with respect to
index 0000
EPA0001 12884902403 Exclusive row write lock, plus insert and
anti-insert row position locks with respect to
index 0001
EPT 528 Exclusive row write lock, plus anti-insert row
position lock with respect to sequential order
S 4294967821 Shared row read lock
SPA0000 1095216660986 Shared row read lock, plus insert and
anti-insert row position locks with respect to
index 0000
SPA0001 1095216661028 Shared row read lock, plus insert and
anti-insert row position locks with respect to
index 0001
SPT 553 Shared row read lock, plus anti-insert row
position lock with respect to sequential order
E (NULL) Exclusive table schema lock
EPT (NULL) Exclusive table schema lock, plus update
intent table contents lock
338 Chapter 9: Protecting
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
lock_type lock_name Description
S (NULL) Shared table schema lock
SAT (NULL) Shared table schema lock, plus table contents
read lock
SPAT (NULL) Shared table schema lock, plus table contents
read and update intent locks
SPT (NULL) Shared table schema lock, plus table contents
update intent lock
A single connection isn’t prevented from obtaining different kinds of locks on
the same table or row; conflicts only arise between different connections. For
example, one connection cannot obtain an insert lock on a row position while
another connection has an anti-insert lock on the same row position, but a single
connection can obtain both kinds of locks on the same position.
When a lock is no longer needed by a connection, it is said to be released,
and SQLAnywhere deletes the entry from the internal lock table. Most locks
persist from the time they are acquired by a connection until the next time that
connection performs a COMMIT or ROLLBACK operation. However, some
locks are released earlier, and others can last longer. For example, a read lock
that is acquired by a FETCH operation in order to ensure cursor stability at iso-
lation level 1 will be released as soon as the next row is fetched. Also, the
exclusive table lock acquired by a LOCK TABLE statement using the WITH
HOLD clause will persist past a COMMIT; indeed, if the table is dropped and
recreated, the table lock will be resurrected automatically, and it won’t released
until the connection is dropped. Cursor stability is discussed in the following
section, as are some performance improvements made possible by the LOCK
TABLE statement.
For all practical purposes, however, all row locks acquired during a transac
-
tion are held until the transaction ends with a COMMIT or ROLLBACK, and at
that point all the locks are released. This is true of statements that fail as well as
those that succeed. Single SQL statements like INSERT, UPDATE, and
DELETE are atomic in nature, which means that if the statement fails, any
changes it made to the database will be automatically undone. That doesn’t
apply to the locks, however; any locks obtained by a failed statement will per
-
sist until the transaction ends.
9.7 Blocks and Isolation Levels
A block occurs when a connection requests a lock that cannot be granted. By
default, a block causes the blocked connection to wait until all conflicting locks
are released. The database option BLOCKING may be set to 'OFF' so that a
blocked operation will be immediately cancelled and an error will be returned to
the blocked connection. The cancellation of a blocked operation does not imply
an automatic rollback, however; the affected connection may proceed forward
and it still holds any locks it may have acquired earlier, including locks acquired
during earlier processing of the failed statement.
Chapter 9: Protecting
339
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
The number of locks held at any one time by a single connection can vary
from zero to several million. The actual number depends on two main factors:
the kinds of SQL operations performed during the current transaction and the
setting of the ISOLATION_LEVEL database option for the connection when
each operation was performed. Some operations, such as UPDATE, require
locks regardless of the isolation level. Other operations, such as SELECT, may
or may not require locks depending on the isolation level.
The isolation level is a number 0, 1, 2, or 3, which represents the degree to
which this connection will be protected from operations performed by other
connections.
n
Isolation level 0 prevents overlapping data changes, data retrievals overlap
-
ping with schema changes, and deadlock conditions. Figures 9-2 through
9-5 and 9-20 show how overlapping transactions are affected by isolation
level 0.
n
Isolation level 1 prevents dirty reads and cursor instability, in addition to
the protection provided by isolation level 0. Figures 9-6 through 9-9 dem
-
onstrate the effects of isolation level 1.
n
Isolation level 2 prevents non-repeatable reads and update instability, in
addition to the protection provided by isolation levels 0 and 1. Figures 9-10
through 9-13 show how repeatable reads and update stability is achieved at
isolation level 2.
n
Isolation level 3 prevents phantom rows and a particular form of lost
update, in addition to the protection provided by isolation levels 0, 1, and 2.
Figures 9-14 through 9-17 demonstrate the effects of isolation level 3.
Isolation levels 2 and 3 result in the largest number of locks and the highest
level of protection at the cost of the lowest level of concurrency. Figures 9-18
and 9-19 show how high isolation levels affect concurrency.
9.7.1 Isolation Level 0
Isolation level 0 is the default; it results in the fewest number of locks and the
highest degree of concurrency at the risk of allowing inconsistencies that would
be prevented by higher isolation levels.
Figure 9-2 is the first of several demonstrations of locks and blocks, all of
which involve two connections, one table, and various values of isolation level.
Here is the script used to create and fill the table with five rows; this script is the
starting point for Figures 9-2 through 9-20:
CREATE TABLE DBA.t1 (
k1 INTEGER NOT NULL PRIMARY KEY,
c1 VARCHAR ( 100 ) NOT NULL );
INSERT t1 VALUES ( 1, 'clean' );
INSERT t1 VALUES ( 3, 'clean' );
INSERT t1 VALUES ( 5, 'clean' );
INSERT t1 VALUES ( 7, 'clean' );
INSERT t1 VALUES ( 9, 'clean' );
COMMIT;
Figure 9-2 shows what happens when Connection A updates a row and then
Connection B attempts to update and delete the same row before Connection A
executes a COMMIT or ROLLBACK; both operations performed by
340 Chapter 9: Protecting
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Connection B are blocked because Connection A has an exclusive write lock on
that row.
Here is a description of the six columns appearing in Figure 9-2 and the other
figures to follow:
n
The step number 1, 2, 3 lists the order in which each separate SQL com-
mand was performed on one or the other of the two connections. Steps 1
and 2 in each figure show what value of ISOLATION_LEVEL is explicitly
set for each connection. For the purposes of Figure 9-2, the isolation level
doesn’t matter; an UPDATE always blocks an UPDATE or a DELETE.
n
The Connection A column shows each SQL statement executed on one of
the connections.
n
Connection B shows the SQL statements executed on the other connection.
n
The Comment column describes any interesting situation that arises when
this step is completed. In Figure 9-2 it shows that Connection B is blocked
from executing the UPDATE and DELETE statements in Steps 4 and 5. For
the purposes of all but one of these figures, the BLOCKING option is set to
'OFF' for both connections so there’s no waiting; a blocked statement is
immediately cancelled and the SQLSTATE is set to '42W18' to indicate an
error. Note that a block doesn’t cause a rollback or release any locks.
n
The c1 Value column contains the value of the t1.c1 column for steps that
SELECT or FETCH a particular row. This value is important in later fig
-
ures but not in Figure 9-2.
n
The column Locks Held byA&Bshows all the locks held by Connection
A and B after each step is executed. This column shows the locks as they
exist at this point in time, not necessarily the locks that were acquired by
this step. For example, the write lock that first appears in Step 3 was
acquired by that step and persists through Steps 4 and 5. The letter A or B
preceding the description of each lock shows which connection holds the
lock.
Simplified lock descriptions are shown in the Locks Held byA&Bcolumn
because the purpose of these figures is to explain how locks, blocks, and isola
-
tion levels affect concurrency and consistency, not to explain the inner workings
of lock management in SQL Anywhere. Here’s a list of the simplified descrip
-
tions and what they mean in terms of the definitions from Section 9.6:
n
Write (E) is used to represent an exclusive row write lock.
Chapter 9: Protecting
341
Figure 9-2. UPDATE blocks UPDATE, DELETE
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
n
Read (S) is used to represent a shared row read lock.
n
Anti-insert (S) is used to represent the combination of a shared row read
lock and an anti-insert row position lock.
n
Anti-insert + Insert (S) is used to represent the combination of three locks:
a shared row read lock plus anti-insert and insert row position locks.
n
Schema (S) is used to represent a shared table schema lock, with or without
a table contents update intent lock.
Note: Chained mode is assumed for Figures 9-2 through 9-20, and the
transaction starting and ending points aren’t explicitly shown. Chained mode is
described in Section 9.3, “Transactions”; it means that transactions are implicitly
started by the first INSERT, UPDATE, or DELETE statement, or SELECT statement
that acquires locks, shown in the Connection A and Connection B columns.
These transactions end when an explicit COMMIT or ROLLBACK statement is
executed.
Figure 9-3 shows that a row deleted by Connection A cannot be re-inserted by
Connection B before Connection A commits the change. This is true regardless
of the isolation level. Connection A must be able to roll back the delete, thus
effectively re-inserting the row itself; if Connection B was allowed to re-insert
the row, Connection A’s rollback would cause a primary key conflict. What does
happen is that Connection B’s insert is blocked; Connection A holds a write
lock on the row, as well as an anti-insert lock to prevent other connections from
re-inserting the row. It also holds an insert lock so that it can re-insert the row in
the case of a rollback. Connection B is free to wait or reattempt the insert later;
if Connection A commits the change, Connection B can then insert the row, but
if Connection A rolls back the delete, Connection B’s insert will fail.
The scenario shown in Figure 9-3 depends on the existence of a primary key in
table t1. If there had been no primary key, Connection A would not have
obtained the anti-insert and insert locks in Step 3, there would have been no
block in Step 4, and Connection B would have been able to insert the row.
Figure 9-4 shows that a row inserted by Connection A cannot be updated or
deleted by Connection B until Connection A commits the change, regardless of
the isolation level. Connection A has complete control over the new row until it
does a commit or rollback; until that point, Connection A must be free to per
-
form other operations on that row without interference, and an update or delete
342 Chapter 9: Protecting
Figure 9-3. DELETE blocks INSERT
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
by Connection B would certainly fall into that category. As with Figure 9-3,
Connection B is free to wait or reattempt the operations later. If Connection A
commits, subsequent update and delete operations will work; if Connection A
rolls back the insert, Connection B won’t be able to do an update or delete.
Figure 9-5 shows that a simple SELECT, even at isolation level 0, obtains a
schema lock on the table. These locks have no effect on any other connection
except to prevent schema changes; in this example, the SELECT by Connection
A prevents Connection B from creating an index. Applications running at isola-
tion level 0 rarely do commits after retrieving rows; in a busy environment that
can mean most tables are subject to perpetual schema locks, making schema
changes a challenge. The opposite effect is even more dramatic: Once a schema
change begins, no other connection can do anything with the affected table until
the schema change is complete. Schema changes during prime time are not rec-
ommended, and the locks and blocks they cause aren’t discussed any further in
this book.
9.7.2 Isolation Level 1
Figure 9-6 shows the first example of interconnection interference that is per
-
mitted at isolation level 0: the dirty read. In Step 3 Connection A updates a row
that is immediately read by Connection B in Step 4. This is called a “dirty read”
because the change by Connection A has not been committed yet; if that change
is eventually rolled back, it means that Connection B is working with dirty data
at Step 4.
Chapter 9: Protecting
343
Figure 9-4. INSERT blocks UPDATE , DELETE
Figure 9-5. SELECT blocks schema change
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Figure 9-7 shows how dirty reads are prevented for a connection running at iso
-
lation level 1. The SELECT at Step 4 is blocked because Connection A has a
write lock on that row, and a write lock blocks a read at isolation level 1. SQL
Anywhere blocks dirty reads altogether, rather than implementing a solution
that returns some older, unchanged value that doesn’t actually exist anymore.
Figure 9-7 shows that no extra long-term locks are required to prevent dirty
reads. The reason Connection B was blocked in Step 4 is because it attempted to
get a short-term lock on the row for the duration of the SELECT, and that
attempt ran afoul of Connection A’s write lock. This short-term lock does not
appear in the Locks Held byA&Bcolumn because it was not granted, and
sa_locks only shows the locks that are granted at the instant the sa_locks is
called (in these examples, at the end of each step). Short-term locks are the
mechanism whereby dirty reads are prevented at isolation level 1.
A dirty read is not necessarily a bad thing; it depends on the application.
For example, if one connection updates column X and then another connection
reads column Y from the same row, that might not be considered a “dirty read”
from an application point of view, but nevertheless it is prevented by isolation
level 1. Another point to consider is the fact that most updates are committed,
not rolled back; just because a change has not been committed yet doesn’t nec
-
essarily mean the data is incorrect from an application point of view.
344 Chapter 9: Protecting
Figure 9-6. Dirty read permitted at isolation level = 0
Figure 9-7. Dirty read prevented at isolation level = 1
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Figure 9-8 shows another form of interference that’s allowed at isolation
level 0: cursor instability. At Step 7, Connection B has fetched the row with k1
= 5, and in Steps 8 and 9 that row is changed by Connection A and the change is
immediately committed. When Connection B updates the same row in Step 10,
it isn’t blocked because Connection A doesn’t hold a write lock on that row any
-
more. However, the change made by Connection A isn’t the one that’s expected.
The SET c1 = c1 + 'er' clause doesn’t change “clean” to “cleaner,” it changes
“dirty” to “dirtyer”; the final incorrect (unlucky?) result is shown in Step 13.
This form of interference is called “cursor instability” because another connec
-
tion is allowed to change a row that was most recently fetched in a cursor loop.
Figure 9-9 shows how isolation level 1 guarantees cursor stability; once the row
has been fetched by Connection B in Step 7, the update by Connection A in
Step 8 is blocked. Now the update by Connection B in Step 9 has the expected
result: “clean” is changed to “cleaner” as shown in Step 11.
Cursor stability is implemented at isolation level 1 by the read locks estab
-
lished for each fetch; for example, the read lock acquired by Connection B in
Step 7 blocks Connection A’s attempt to acquire a write lock in Step 8.
Each of these read locks is released as soon as the next row is fetched and a
new read lock is acquired on that row. This early release of cursor stability read
locks is an exception to the rule of thumb that “all row locks are held until the
end of a transaction.”
Chapter 9: Protecting
345
Figure 9-8. Cursor stability not ensured at isolation level = 0
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
[...]... so rather than let them both wait forever SQLAnywhere automatically cancels the update in Step 8 and tells Connection B about the problem with SQLSTATE '40001' By default, SQLAnywhere extends its handling of the cyclical deadlock SQLSTATE '40001' in a special way: If SQLSTATE is still set to '40001' when processing of the current operation is complete, SQLAnywhere automatically executes a ROLLBACK... As noted earlier, SQLAnywhere sets the SQLSTATE to '40W06' when it cancels an operation because it detected a thread deadlock In this case SQLAnywhere does not execute the automatic ROLLBACK described earlier in the discussion of cyclical deadlock However, from an application point of view the SQLSTATE may be the same as that returned for a cyclical deadlock: '40001' That’s because SQLSTATE values... SQLSTATE values go through a translation process for certain client interfaces, including ODBC; these alternate SQLSTATE values are documented in the SQLAnywhere Help Figure 9-2 1 shows the Help description for thread deadlock: The SQLCODE is -307 and the SQLSTATE inside the engine is '40W06', but the SQLSTATE returned to applications using an ODBC Version 2 or Version 3 interface is changed to '40001' as... Note: SQLAnywhere doesn’t execute an automatic ROLLBACK for any other SQLSTATE, just '40001' And it doesn’t have to be an actual cyclical deadlock condition; a SIGNAL statement that sets SQLSTATE to '40001' will also cause the automatic ROLLBACK unless an exception handler or some other logic sets SQLSTATE to some other value before the current operation is complete In the example shown in Figure 9-2 0,... thread deadlock arises At this point no work can proceed; rather than let all the threads wait forever, SQLAnywhere automatically cancels one of the blocked operations and tells the connection about the problem with SQLSTATE '40W06' and the error message “All threads are blocked.” By default, the SQLAnywhere network server dbsrv9.exe has 20 threads in its pool, and the personal server dbeng9.exe has... these connections are doing different work; the thread deadlock is artificial, caused by a design flaw 9.9 Mutexes The SQLAnywhere engine can use multiple CPUs to handle SQL operations Each operation is handled by one CPU rather than split across multiple CPUs, but it is possible for SQLAnywhere to handle requests from more than one connection at the same time Ideally, n CPUs should be able to handle... no delimiters are required around "C 2", 'QWER ASDF', or the empty string used as a password for user ids B or E "%ASANY9%\win32\dbisql.exe" "%ASANY9%\win32\dbisql.exe" "%ASANY9%\win32\dbisql.exe" "%ASANY9%\win32\dbisql.exe" -c -c -c -c "ENG=test9;DBN=test9;UID=A;PWD =sql; CON=A" "ENG=test9;DBN=test9;UID=B;PWD=;CON=B" "ENG=test9;DBN=test9;UID=C 2;PWD=QWER ASDF" "ENG=test9;DBN=test9;UID=E;PWD=" Please... is which, whereas the task bar title for user id E is cluttered up with the server name Figure 9-2 2 Connection names appear in ISQL task bar titles The terms “user,” “user id,” and “user name” are often used interchangeably to refer to the identifier named in GRANT and other SQL statements Inside the SQLAnywhere catalog, however, there is a distinction between the user_id and user_name columns in... application This default behavior can be avoided by using a BEGIN block with an exception handler that catches the SQLSTATE '40001' and doesn’t execute a RESIGNAL statement to pass the exception onward; in this case SQLSTATE will be set back to '00000' before returning to the client application and SQLAnywhere won’t execute the automatic ROLLBACK With or without this ROLLBACK, the affected connection is free... Protecting 351 Figure 9-1 6 DELETE suppresses UPDATE at isolation level . SQL Anywhere creates the lock, the request is
said to be granted, the lock is said to be acquired, and the work of that connec
-
tion can proceed. If SQL. overlap
-
ping with schema changes, and deadlock conditions. Figures 9-2 through
9-5 and 9-2 0 show how overlapping transactions are affected by isolation
level