San*_*ira 1 .net c# mysql locking
我做了这个测试,从两个线程中选择一个我之前创建的行:
CREATE TABLE `customers` (
`id` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`),
) ENGINE=InnoDB
var t1 = new Thread(new ThreadStart(delegate()
{
using (var conn = new MySqlConnection("Server=localhost;Database=test;Uid=root;Pwd=test;"))
{
conn.Open();
using (var trans = conn.BeginTransaction())
{
using (var cmd = new MySqlCommand("select id from customers where id = 8534 FOR UPDATE;", conn, trans))
{
using (var reader = cmd.ExecuteReader())
{
Console.WriteLine("Enter t1: " + reader.Read());
Thread.Sleep(2000);
Console.WriteLine("Exit t1");
}
}
}
};
}));
var t2 = new Thread(new ThreadStart(delegate()
{
using (var conn = new MySqlConnection("Server=localhost;Database=test;Uid=root;Pwd=test;"))
{
conn.Open();
using (var cmd = new MySqlCommand("select id from customers where id = 8534", conn))
{
Console.WriteLine("Enter t2: " + cmd.ExecuteScalar());
Console.WriteLine("Exit t2");
}
}
}));
t1.Start();
Thread.Sleep(400);
t2.Start();
t1.Join();
t2.Join();
Run Code Online (Sandbox Code Playgroud)
我得到的结果是:
Enter t1: True
Enter t2: 8534
Exit t2
Exit t1
Run Code Online (Sandbox Code Playgroud)
线程1中的FOR UPDATE是否应该阻止线程2在释放事务之前读取该行?
FOR UPDATE在线程1中是否应该阻止线程2在释放事务之前读取该行?
没有.
但它会阻止线程2写入此行(或者也可以使用FOR UPDATE子句读取它).
在默认事务隔离级别(即REPEATABLE READ)中,SELECT语句不会对它们读取的行放置任何锁定.
对于SELECT语句来锁定你应该指示它锁(通过使用FOR UPDATE,LOCK IN SHARE MODE或将读取的事务隔离级别SERIALIZABLE).
来自文档:
一致性读取是
InnoDB进程SELECT语句READ COMMITTED和REPEATABLE READ隔离级别的默认模式.一致读取不会对其访问的表设置任何锁定,因此其他会话可以在对表执行一致读取的同时自由修改这些表.
和
InnoDB对select子句使用一致读取INSERT INTO ... SELECT, UPDATE ... (SELECT),并且CREATE TABLE ... SELECT不指定FOR UPDATE或者LOCK IN SHARE MODE是否innodb_locks_unsafe_for_binlog设置了选项,并且事务的隔离级别未设置为SERIALIZABLE.因此,在从所选表读取的行上没有设置锁.否则,InnoDB使用更强的锁定,SELECT部分就像READ COMMITTED,每个一致的读取,即使在同一个事务中,也会设置和读取自己的新快照.
| 归档时间: |
|
| 查看次数: |
1292 次 |
| 最近记录: |