Three kinds of problems that may arise from concurrency
Dirty Read
definition : A transaction has read the modification of a transaction during the execution, but a transaction is not finished (committed), and a transaction may succeed or fail later.
analogy : A modified the source code and did not submit to the source code system, a directly through the QQ code to the B,a later canceled the modification.
code example
Copy Code code as follows:
[TestMethod]
public void Dirty Read _ Test ()
{
Predecessor condition
using (var context = new Testentities ())
{
Assert.AreEqual (1, context. Tables.count ());
}
var AutoResetEvent = new AutoResetEvent (false);
var transactionOptions1 = new Transactionoptions {isolationlevel = isolationlevel.readcommitted};
var transactionOptions2 = new Transactionoptions {isolationlevel = isolationlevel.readuncommitted};
using (var ts1 = new TransactionScope (transactionscopeoption.required, transactionOptions1))
{
Add data
using (var context = new Testentities ())
{
Context. Tables.add (New Table () {Id = Guid.NewGuid (), Name = "De Guangwei"});
Context. SaveChanges ();
}
ThreadPool.QueueUserWorkItem (Data =>
{
using (var ts2 = new TransactionScope (transactionscopeoption.required, TransactionOptions2))
{
Dirty Read Test
using (var context = new Testentities ())
{
Assert.AreEqual (2, context. Tables.count ());
}
}
AutoResetEvent.Set ();
});
Autoresetevent.waitone ();
}
Predecessor condition
using (var context = new Testentities ())
{
Assert.AreEqual (1, context. Tables.count ());
}
}
Do not read repeatedly
definition : A transaction read two times, during which the B transaction modified the data, and the data from the two readings of a transaction was different (not repeatable).
analogy : A In doing the source code review, in the process of the review to obtain two times source code, in the two acquisition period B modified the source code, B is likely to modify a review of the code, and this part of the code may not conform to the specification.
code example
Copy Code code as follows:
[TestMethod]
public void non-repeatable read _ Test ()
{
var AutoResetEvent = new AutoResetEvent (false);
var transactionOptions1 = new Transactionoptions {isolationlevel = isolationlevel.readcommitted};
var transactionOptions2 = new Transactionoptions {isolationlevel = isolationlevel.readcommitted};
using (var ts1 = new TransactionScope (transactionscopeoption.required, transactionOptions1))
{
Predecessor condition
using (var context = new Testentities ())
{
Assert.AreEqual ("Li Yu Girl", context. Tables.first (). Name);
}
ThreadPool.QueueUserWorkItem (Data =>
{
using (var ts2 = new TransactionScope (transactionscopeoption.required, TransactionOptions2))
{
modifying data
using (var context = new Testentities ())
{
Context. Tables.first (). Name = "De Guangwei";
Context. SaveChanges ();
}
Ts2.complete ();
}
AutoResetEvent.Set ();
});
Autoresetevent.waitone ();
Non-repeatable READ test
using (var context = new Testentities ())
{
Assert.AreEqual ("De Guangwei", context. Tables.first (). Name);
}
}
}
Phantom Reading
definition : A transaction reads two of data, and during this two reads the B transaction adds data, and the collection of the two reads from a transaction is different (phantom reading).
analogy : A in the statistical file data, in order to statistical accurate a statistics two times, in these two statistics process B added a file, a found that the number of these two statistics is not the same (phantom reading), a will feel their head a little headache.
code example
Copy Code code as follows:
[TestMethod]
public void Phantom Read _ Test ()
{
var AutoResetEvent = new AutoResetEvent (false);
var transactionOptions1 = new Transactionoptions {isolationlevel = isolationlevel.repeatableread};
var transactionOptions2 = new Transactionoptions {isolationlevel = isolationlevel.readcommitted};
using (var ts1 = new TransactionScope (transactionscopeoption.required, transactionOptions1))
{
Predecessor condition
using (var context = new Testentities ())
{
Assert.AreEqual (1, context. Tables.count ());
}
ThreadPool.QueueUserWorkItem (Data =>
{
using (var ts2 = new TransactionScope (transactionscopeoption.required, TransactionOptions2))
{
Add data
using (var context = new Testentities ())
{
Context. Tables.add (New Table () {Id = Guid.NewGuid (), Name = "De Guangwei"});
Context. SaveChanges ();
}
Ts2.complete ();
}
AutoResetEvent.Set ();
});
Autoresetevent.waitone ();
Phantom reading Test
using (var context = new Testentities ())
{
Assert.AreEqual (2, context. Tables.count ());
}
}
}
How to handle concurrency problems with four isolation levels
|
Dirty Read |
Do not read repeatedly |
Phantom reading |
Read not submitted |
Allow |
Allow |
Allow |
Read submitted |
Not allowed |
Allow |
Allow |
REPEATABLE READ |
Not allowed |
Not allowed |
Allow |
Serialization |
Not allowed |
Not allowed |
Not allowed |