我的网站上有一个函数可以很快地将一堆值保存到同一个DataObject类型中.大部分时间都可以,但偶尔我会收到错误
ERROR: duplicate key value violates unique constraint …
阅读文档,我看到:
SilverStripe does not use the database‘s built-in auto-numbering system. Instead, it will generate a new ID by adding 1 to the current maximum ID
以前查看代码看起来它从主键检索最大数量,插入带有该ID的记录,然后设置DataObject的值并再次写入.在我的负载平衡环境中,当发送这些多个条目时,我认为插入是使用相同的主键发生的,因此是错误.
据我所知,这是一个我无法解决的问题.从其他questions和doco我无法设置复合主键.我唯一能想到的是为使用DB内置自动编号系统的create运行自定义sql.
编辑
完整的错误是
Query Failed: ERROR: duplicate key value violates unique constraint 'TABLE_pkey'
DETAIL: Key ('ID')=(136) already exists.
声明:
INSERT INTO "TABLE" ("ClassName", "Name", "MemberID", "OtherTabeID", "Value", "LastEdited", "Created", "ID") VALUES ($1, $2, $3, $4, $5, $6, $7, $8),Array)
我读这个是因为它从先前确定的值插入ID而不是依赖于DB自动增量.那是对的吗?
编辑2
查看日志,看起来INSERT首先使用Created字段完成,然后选择语句来获取ID:
SELECT last_value FROM "TABLENAME_ID_seq"
然后在保存附加细节的情况下完成更新.
我觉得这可能是一种竞争条件会导致保存到不正确的行,但不会导致我目前遇到的情况.理想情况下,任何INSERT都将具有将用于更新命令的返回“ID”.
编辑3
上面的过程与我所拥有的堆栈跟踪相反,后者显示插入包含的不仅仅是Created:
pg_query_params(Resource id #154,INSERT INTO "TABLENAME" ("ClassName", "Name", "MemberID", "OTHERTABLEID", "Value", "LastEdited", "Created", "ID") VALUES ($1, $2, $3, $4, $5, $6, $7, $8),Array)
PostgresqlConnector.PHP:200
PostgresqlConnector->preparedQuery(INSERT INTO "TABLENAME" ("ClassName", "Name", "MemberID", "OTHERTABLEID", "Value", "LastEdited", "Created", "ID") VALUES (?, ?, ?, ?, ?, ?, ?, ?),Array,256)
Database.PHP:143
SS_Database->{closure}(INSERT INTO "TABLENAME" ("ClassName", "Name", "MemberID", "OTHERTABLEID", "Value", "LastEdited", "Created", "ID") VALUES (?, ?, ?, ?, ?, ?, ?, ?))
Database.PHP:193
SS_Database->benchmarkQuery(INSERT INTO "TABLENAME" ("ClassName", "Name", "MemberID", "OTHERTABLEID", "Value", "LastEdited", "Created", "ID") VALUES (?, ?, ?, ?, ?, ?, ?, ?),Closure,Array)
Database.PHP:146
SS_Database->preparedQuery(INSERT INTO "TABLENAME" ("ClassName", "Name", "MemberID", "OTHERTABLEID", "Value", "LastEdited", "Created", "ID") VALUES (?, ?, ?, ?, ?, ?, ?, ?),Array,256)
DB.PHP:365
DB::prepared_query(INSERT INTO "TABLENAME" ("ClassName", "Name", "MemberID", "OTHERTABLEID", "Value", "LastEdited", "Created", "ID") VALUES (?, ?, ?, ?, ?, ?, ?, ?),Array)
sqlExpression.PHP:121
解决方法:
文档中的说明非常过时(即使2007年的SilverStripe 2.1具有正确的行为),文档描述的方法也会导致竞争条件.
复杂性是SilverStripe使用多表继承,SilverStripe所做的是这样的情况:
>插入SiteTree表
>获取生成的ID
>使用相同的ID插入Page表(和其他表)
它也可以使用相同的ID对SiteTree表进行后续UPDATE写入.
不幸的是,这并不一定能帮助您解决问题,但它至少可以解决问题的一个可能来源.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。