插入唯一文本需要什么最低隔离级别?
What minimum isolation level is required for inserting unique text?
我有一个 table,其中的文本列需要唯一性保证。由于我不能对文本列设置唯一性约束,我想使用事务来包围我的插入以确保唯一性保证。
我的问题是:此保证要求的最低隔离级别是多少?
没有使用确保唯一性的事务。
为此使用 UNIQUE
约束。
但是你不能建立超过768字节的索引,包括唯一索引。这意味着您不能对 TEXT
、VARCHAR
等超过一定长度的长字符串数据类型施加唯一约束
您可以使用 前缀索引 使长字符串的前导部分唯一。
ALTER TABLE MyTable ADD UNIQUE KEY (textfield(255));
确保唯一性的另一种方法是在现有行中搜索要插入的值,只有在找不到时才插入新值。
但这需要您拥有对 table 的独占访问权,以防止与另一个试图插入相同值的并发会话发生竞争。
这也与事务隔离级别无关。即使 SERIALIZABLE
隔离级别也无法帮助您避免竞争条件。阅读 http://dev.mysql.com/doc/refman/5.7/en/innodb-transaction-isolation-levels.html 上面写着:
[SERIALIZABLE] is like REPEATABLE READ
, but InnoDB implicitly converts all plain SELECT
statements to SELECT ... LOCK IN SHARE MODE
if autocommit is disabled.
因此,如果多个会话同时尝试读取 table 以检查重复值,则允许它们这样做,因为共享锁不会阻塞其他共享锁。然后他们可能 所有 决定插入新值是安全的,并且您有重复项。
要在读取 table 时获得独占锁定,您需要明确使用 SELECT ... FOR UPDATE
。但是您可以在任何事务隔离级别执行此操作。
我有一个 table,其中的文本列需要唯一性保证。由于我不能对文本列设置唯一性约束,我想使用事务来包围我的插入以确保唯一性保证。
我的问题是:此保证要求的最低隔离级别是多少?
没有使用确保唯一性的事务。
为此使用 UNIQUE
约束。
但是你不能建立超过768字节的索引,包括唯一索引。这意味着您不能对 TEXT
、VARCHAR
等超过一定长度的长字符串数据类型施加唯一约束
您可以使用 前缀索引 使长字符串的前导部分唯一。
ALTER TABLE MyTable ADD UNIQUE KEY (textfield(255));
确保唯一性的另一种方法是在现有行中搜索要插入的值,只有在找不到时才插入新值。
但这需要您拥有对 table 的独占访问权,以防止与另一个试图插入相同值的并发会话发生竞争。
这也与事务隔离级别无关。即使 SERIALIZABLE
隔离级别也无法帮助您避免竞争条件。阅读 http://dev.mysql.com/doc/refman/5.7/en/innodb-transaction-isolation-levels.html 上面写着:
[SERIALIZABLE] is like
REPEATABLE READ
, but InnoDB implicitly converts all plainSELECT
statements toSELECT ... LOCK IN SHARE MODE
if autocommit is disabled.
因此,如果多个会话同时尝试读取 table 以检查重复值,则允许它们这样做,因为共享锁不会阻塞其他共享锁。然后他们可能 所有 决定插入新值是安全的,并且您有重复项。
要在读取 table 时获得独占锁定,您需要明确使用 SELECT ... FOR UPDATE
。但是您可以在任何事务隔离级别执行此操作。