【发布时间】:2014-06-11 07:34:20
【问题描述】:
我想知道有没有办法在不隐式提交事务的情况下锁定 MySQL 表。
假设我有两个表(table_1、table_2),并且我将数据与事务同时插入到这些表中。而且我需要锁定“table_2”,以便其他用户在事务完成之前无法写入/修改“table_2”。我的问题是当我锁定 table_2 时,事务是隐式提交的。是的,我知道 MySQL 文档中对此进行了解释
LOCK TABLES 不是事务安全的,它会隐式提交任何活动的 尝试锁定表之前的事务
我想知道是否有任何其他事务安全的方法来进行表锁定。
这是我的 C# 代码段
MySQLTransaction trans = conn.BeginTransaction();
command.Transaction = trans;
command.CommandText = "INSERT INTO table_1 VALUES ('val1', 'val2')";
command.ExecuteNonQuery();
command.CommandText = "LOCK TABLES table_2 WRITE";
command.ExecuteNonQuery();
command.CommandText = "INSERT INTO table_2 VALUES ('val1', 'val2')";
command.ExecuteNonQuery();
command.CommandText = "RELEASE TABLES";
command.ExecuteNonQuery();
trans.Commit();
在不提交事务的情况下锁定和插入数据到“table_2”有什么想法吗?
提前致谢
【问题讨论】:
-
您的表使用什么存储引擎?如果他们使用事务引擎(例如 InnoDB),那么您不需要显式锁定您的表:仅在事务中执行插入操作(如您所做的那样)应该确保它们与并发会话隔离。您面临的实际问题是什么?
-
是的,它是 InnoDB。我想确保在事务完成之前没有人可以读取/修改 table_2。如果某些用户在事务完成之前访问了“table_2”,那么准确性将是一个问题。
-
不,不会。将您的操作封装在事务中的全部意义是将它们与并发会话隔离:只有在您提交事务时,插入才会对其他会话自动可见 - 直到那时,它们才可见在交易本身。只需删除您的
LOCK TABLES和RELEASE TABLES命令即可。 -
我需要为事务使用任何隔离级别吗?
-
所有事务都使用隔离级别。选择的级别只影响从事务外部看到的从内部看到的变化;因此,您可能希望为您的其他事务选择适当的隔离级别 - 默认级别
REPEATABLE_READ应该足以满足大多数用例。
标签: c# mysql transactions