我正在使用ActiveRecord模型来保存数据。
Unique Validator
非常完美。但是当我如此快速地插入数据时,它就不再完美。在某些请求中,我得到Yii无法捕获的错误。
完整性约束违规 - yii \ db \ IntegrityException SQLSTATE [23000]:完整性约束违规:1062重复条目 ' ***' ...
我们是否有任何解决方案来处理此问题而不添加其他服务?
谢谢!
答案 0 :(得分:1)
总结评论......
您最需要的是在验证之前手动锁定表并在其之后释放锁定。 Yii2提供optimistic locks机制但它不适合您的情况。仅在更新和删除方法中支持乐观锁:
只有在更新或删除时才支持乐观锁定 使用yii \ db \ ActiveRecord :: update()或的现有数据行 yii \ db \ ActiveRecord :: delete(),分别为。
此外,当更新失败时,由于冲突(没有实际的表锁定),乐观锁只会引发异常。
解决方案取决于您的数据库引擎。 Yii2提供了用于手动锁定的互斥机制。开箱即用的Yii2支持Mysql和Postgres。请参阅Yii2手册的以下页面中的组件说明:
因此,在配置了配置中的互斥锁后(官方指南中的pgsql示例):
[
'components' => [
'db' => [
'class' => 'yii\db\Connection',
'dsn' => 'pgsql:host=127.0.0.1;dbname=demo',
]
'mutex' => [
'class' => 'yii\mutex\PgsqlMutex',
],
],
]
你需要做那样的事情
\Yii::$app->mutex->acquireLock($lockingObject);
// validate uniqueness and save
\Yii::$app->mutex->releaseLock($lockingObject);
或,您肯定可以使用RDBMS的SQL语法手动执行此操作。
SELECT GET_LOCK('tablename',10);
SELECT RELEASE_LOCK('tablename');
LOCK TABLE tablename IN SHARE ROW EXCLUSIVE MODE;
请注意,Pgsql锁只能在事务内部工作。
答案 1 :(得分:0)
我解决这个问题的方法:
Unique Validator
在这种情况下不起作用INSERT IGNORE
忽略新记录(如果存在)。它的工作非常快。