问题
I have a few questions regarding subject from the title. First of all, lets assume that we work with JDBC, and there we have 2 transactions T1 and T2. In T1 we execute select statement on one particular row. Then we execute update on that row. In transaction T2 we execute select statement on the same row.
Here are the questions:
1) When does transaction T1 acquire the lock on mentioned row? I assume it happens during select statement execution?
2) How long transaction T1 holds the lock? Does it hold it until the transaction is committed/rolled back, or it release the lock before that?
3) Does isolation level controls what type of lock is used? For example:
a) if we use read committed isolation level on transaction T2, does that means that T2 will use shared read lock for select statement, so that in case T1 updated the row already T2 will not have access to that row (avoiding dirty reads), and in case T1 did not update row yet T2 will have read access to that row?
b) If we use read uncommitted isolation level on transaction T2, does that means T2 will use no-lock for select statement, so it can read data even if it is being modified by T1 (allowing for dirty reads).
So, the question that bugs me most is who is in control of deciding what type of locks are applied? Is it isolation level of transaction, or there is some other way?
4) If answer to question 3 is positive (isolation level controls what locks are used), then what happens if we use jdbc over mysql database for example, and we use select for update or select lock in share mode constructs? As I remember first is exclusive lock, while second is shared read lock. How will it reflect on our transaction isolation level?
5) What kind of lock is acquired in case of repeatable read isolation level? Lets assume our T2 (with repeatable read isolation level) have two select statements on the same row while T1 is same as before. First is executed one select statement in T2, then T1 is executed and committed, and after that T2 second select is executed. Is this scenario even possible? If transactions hold their locks until they are committed/rolled back, I assume T1 will not be able to get exclusive lock for update until T2 is completed?
EDIT: One more question:
6) In multiversion concurrency control system, when we set serializable isolation level, transaction A that tries to update some row that is updated by another transaction B (B updated the row after the A started) will be rolled back. I want to ask isn't that pretty same thing that happens in optimistic locking scenarios?
Thanks in advance.
回答1:
Your question is a good one. Understanding what kind of locks are acquired allows a deep understanding of DBMS's. In SQL Server, under all isolation levels (Read Uncommitted, Read Committed (default), Repeatable Reads, Serializable) Exclusive Locks are acquired for Write operations.
Exclusive locks are released when transaction ends, regardless of the isolation level.
The difference between the isolation levels refers to the way in which Shared (Read) Locks are acquired/released.
Under Read Uncommitted isolation level, no Shared locks are acquired. Under this isolation level the concurrency issue known as "Dirty Reads" can occur.
Under Read Committed isolation level, Shared Locks are acquired for the concerned records. The Shared Locks are released when the current instruction ends. This isolation level prevents "Dirty Reads" but, since the record can be updated by other concurrent transactions, "Non-Repeatable Reads" or "Phantom Reads" can occur.
Under Repeatable Reads isolation level, Shared Locks are acquired for the transaction duration. "Dirty Reads" and "Non-Repeatable Reads" are prevented but "Phantom Reads" can still occur.
Under Serializable isolation level, ranged Shared Locks are acquired for the transaction duration. None of the above mentioned concurrency issues occur but performance is drastically reduced and there is the risk of Deadlocks occurrence.
来源:https://stackoverflow.com/questions/7457628/transactions-locks-isolation-levels