C# 对于事务内的更新,不会锁定行
我做这个测试是为了从两个线程中选择一行,这是我之前创建的:C# 对于事务内的更新,不会锁定行,c#,.net,mysql,locking,C#,.net,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=l
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();
我得到的结果是:
Enter t1: True
Enter t2: 8534
Exit t2
Exit t1
线程1中的FOR UPDATE不应该阻止线程2在释放事务之前读取该行吗
线程1中的FOR UPDATE不应该阻止线程2在释放事务之前读取该行吗
没有
但它会阻止线程2写入这一行或用FORUPDATE子句读取这一行
在可重复读取的默认事务隔离级别中,SELECT语句不会对其读取的行放置任何锁
对于要锁定的SELECT语句,您应该通过使用For UPDATE、在共享模式下锁定或将读取器的事务隔离级别设置为SERIALIZABLE来指示它锁定
从:
一致读取是默认模式,InnoDB处理读取提交和可重复读取隔离级别中的SELECT语句。一致读取不会对其访问的表设置任何锁,因此其他会话可以在对表执行一致读取的同时自由修改这些表
及
InnoDB对select in子句(如INSERT INTO。。。选择,更新。。。选择,然后创建表。。。如果设置了innodb_locks_unsafe_FOR_binlog选项且事务的隔离级别未设置为SERIALIZABLE,则选择不指定在共享模式下更新或锁定。因此,不会对从所选表读取的行设置锁。否则,InnoDB将使用更强的锁,选择部分的行为类似于READ COMMITTED,其中每个一致读取(即使在同一事务中)都会设置并读取自己的新快照
线程1中的FOR UPDATE不应该阻止线程2在释放事务之前读取该行吗
没有
但它会阻止线程2写入这一行或用FORUPDATE子句读取这一行
在可重复读取的默认事务隔离级别中,SELECT语句不会对其读取的行放置任何锁
对于要锁定的SELECT语句,您应该通过使用For UPDATE、在共享模式下锁定或将读取器的事务隔离级别设置为SERIALIZABLE来指示它锁定
从:
一致读取是默认模式,InnoDB处理读取提交和可重复读取隔离级别中的SELECT语句。一致读取不会对其访问的表设置任何锁,因此其他会话可以在对表执行一致读取的同时自由修改这些表
及
InnoDB对select in子句(如INSERT INTO。。。选择,更新。。。选择,然后创建表。。。如果设置了innodb_locks_unsafe_FOR_binlog选项且事务的隔离级别未设置为SERIALIZABLE,则选择不指定在共享模式下更新或锁定。因此,不会对从所选表读取的行设置锁。否则,InnoDB将使用更强的锁,选择部分的行为类似于READ COMMITTED,其中每个一致读取(即使在同一事务中)都会设置并读取自己的新快照