Rails 可以在 ActiveRecord 中加入唯一性的验证
我看书,上面说这种方式也会产生问题,也会向数据库插入两条一样的数据,在数据库层再加一次唯一性校验没错
但是我不明白的是:“为什么 rails 不能避免这种重复插入记录的情况呢,它的校验不是和数据库中的记录作对比吗?”,难道和多线程有关系?
希望知道的朋友能帮我指点迷津。
唯一性验证是一个 SELECT, 插入数据是一个 INSERT。常见的写法是 validation 和 create/save 分开。这样,在多个线程请求的时候,可能会出现第一个请求的验证通过后,第二个请求接着写入造成重复数据。这种可能性存在,虽然很小,毕竟几乎同时请求并造成相同数据的概率太低了。
另一个写法是不做 Validation, 直接一个 loop 插入,直到没有重复的数据为止,并包裹在一个 transaction 里面。这样就肯定没问题的了。写入 token 常见这种做法。
A UNIQUE index creates a constraint such that all values in the index must be distinct. An error occurs if you try to add a new row with a key value that matches an existing row. This constraint does not apply to NULL values except for the BDB storage engine. For other engines, a UNIQUE index permits multiple NULL values for columns that can contain NULL. If you specify a prefix value for a column in a UNIQUE index, the column values must be unique within the prefix.
由于 validates_uniqueness_of(*attr_name) 是在 create 操作的时候调用的,所以当用户较多的时候(或者使用多个应用服务器的情况),可能会出现相同记录同时被 create,但是都还没有 save 的情况。因为此时对 rails 来说,数据库里还没有将要创建的记录。在用户提交,记录被保存至数据库的过程中,rails 不会再验证记录是否唯一,所以会造成数据库里有相同记录的情况。
@iBachue ActiveRecord 不是数据库,是 Rails 的一部分。另外,AR 也只会自动加 callback 的部分,其余的逻辑要靠你自己写。
这个不是 rails tutorial 第六章的唯一性验证的问题嘛,不过作者确实没有说清楚。只是说了如果不加数据库验证,任何 rails 程序都会有这样的问题: