Mysql 插入唯一文本所需的最低隔离级别是多少?

Mysql 插入唯一文本所需的最低隔离级别是多少?,mysql,sql,database,isolation-level,Mysql,Sql,Database,Isolation Level,我有一个带有文本列的表,我需要唯一性保证。因为我不能对文本列设置唯一性约束,所以我希望使用事务来包围我的插入,以确保唯一性保证 我的问题是:这个保证所需的最低隔离级别是多少?没有使用确保唯一性的事务 为此使用唯一的约束 但是您不能创建任何超过768字节的索引,包括唯一索引。这意味着您不能对长字符串数据类型(如TEXT、VARCHAR)施加特定长度上的唯一约束 可以使用前缀索引使长字符串的前导部分唯一 ALTER TABLE MyTable ADD UNIQUE KEY (textfield(25

我有一个带有文本列的表,我需要唯一性保证。因为我不能对文本列设置唯一性约束,所以我希望使用事务来包围我的插入,以确保唯一性保证


我的问题是:这个保证所需的最低隔离级别是多少?

没有使用确保唯一性的事务

为此使用
唯一的
约束

但是您不能创建任何超过768字节的索引,包括唯一索引。这意味着您不能对长字符串数据类型(如
TEXT
VARCHAR
)施加特定长度上的唯一约束

可以使用前缀索引使长字符串的前导部分唯一

ALTER TABLE MyTable ADD UNIQUE KEY (textfield(255));
确保唯一性的另一种方法是在现有行中搜索要插入的值,只有在未找到该值时,才插入新值

但这要求您具有对表的独占访问权,以防止另一个并发会话尝试插入相同值时出现竞争条件

这也与事务隔离级别无关。即使是
SERIALIZABLE
隔离级别也无法帮助您避免竞争条件。读一读,上面写着:

[SERIALIZABLE]类似于
可重复读取
,但InnoDB隐式地将所有普通的
SELECT
语句转换为
SELECT。。。如果禁用自动提交,则锁定共享模式

因此,如果多个会话同时尝试读取表以检查重复值,则允许它们读取,因为共享锁不会阻止其他共享锁。然后,他们可能都认为插入新值是安全的,而您有重复的值


要在读取表时获得独占锁定,可以使用
SELECT。。。用于显式更新
。但您可以在任何事务隔离级别中执行此操作。

投票决定将此问题作为重复问题结束。无论如何,没有任何交易行为强制唯一性,所以你无论如何都在追求错误的策略。@BillKarwin我不认为这个问题是如此标记的问题的重复:其他问题的答案提供了替代解决方案(当然,应该使用),但仍然没有回答所问的问题。为了回答这个问题,
SERIALIZABLE
是可以达到的最高值,但仍然不足以保证在所有情况下的唯一性。请看@BillKarwin,这与您发布的内容不同。这个问题是关于使文本唯一所需的隔离级别。另一个问题是关于在文本列上创建唯一约束。请确保我理解:
选择要更新的唯一文本列
可以告诉我唯一文本是否确实存在吗?如果是这样,我是否需要在事务中确保
INSERT unique\u text into table
语句在没有其他会话插入相同的唯一文本的情况下运行?是的,您需要在单个事务中执行SELECT和后续INSERT,否则SELECT FOR UPDATE创建的锁将被释放。但是这与隔离级别无关,但是隔离级别不决定其他会话看到什么吗?也就是说,会话A启动trans,
选择要更新的唯一文本,
将唯一文本插入表中
。会话B启动事务并执行相同的操作。在B的事务
READ_uncommitted
vs
Serializable
中设置隔离级别会产生不同的结果吗?也就是说,
READ\u uncommitted
将看不到A的插入。一旦会话A对某一行(或该行的间隔)使用了独占锁,会话B就无法为同一行的
SELECT for UPDATE
获取锁,因为A拥有该锁。无论会话中的任何事务隔离级别如何,这都是一样的。我只是想确认我的理解,因为已经说了很多。如果所有会话都在事务中使用SELECT和后续INSERT来插入文本列,这将保证该列的唯一性。对吗?