是什么导致我的 SQL 事务在 php 没有注意到的情况下中止?
我正在 PHP 中使用 Postgresql 9.0 从 kohana 3.2 框架执行 SQL 事务,
但出现异常
Database_Exception [ 0 ]:错误:当前事务已中止, 命令被忽略,直到事务块结束 [ SELECT c.* FROM 内容 c WHERE c.content_id = 129 AND EXISTS( SELECT NULL FROM 内容 tmp WHERE tmp.content_id = c.content_id AND c.content_id = 第129章 tmp.content_id分组,最大(tmp.version)=c.version)
我很奇怪,因为这对我来说意味着在此之前的一些 SQL 失败了,因此不再接受任何 SQL 语句。不过,我将所有 SQL 调用都放在 try/catch 块中,并在重新抛出之前对 catch 进行回滚。
所以我永远不应该看到这个异常,对吗?而是期望看到之前的异常,这会破坏事务开始...
我向我的 PHP DB 驱动程序添加了日志记录,并记录了导致问题的以下 SQL 语句。下面的最后一个 SELECT 语句是上面我的异常中引用的语句。
异常语句之前的语句是 INSERT,这将是一个很好的剧透候选者,但是当我手动运行所有这些语句时,它们都会正确执行。
UPDATE "articles"
SET article_id = 126, title = 'abc', blurb = 'abc article blurb'
WHERE "article_id" = 126
SELECT c.* FROM contents c
WHERE c.content_id = 127
AND EXISTS(
SELECT NULL FROM contents tmp
WHERE tmp.content_id = c.content_id AND c.content_id = 127
GROUP BY tmp.content_id HAVING MAX(tmp.version) = c.version
)
SELECT c.* FROM contents c
WHERE c.content_id = 128 AND EXISTS(
SELECT NULL FROM contents tmp
WHERE tmp.content_id = c.content_id AND c.content_id = 128
GROUP BY tmp.content_id HAVING MAX(tmp.version) = c.version
)
INSERT INTO "contents"
("blurb", "content", "content_id", "content_type_id", "title", "author_id", "version", "editor_id")
VALUES
('postit art', 'FEATURE_IMG_david-chan-drawing_IMG_0221.JPG', 128, 2, 'david chan drawing', 5, 2, 4)
SELECT c.* FROM contents c
WHERE c.content_id = 129 AND EXISTS(
SELECT NULL FROM contents tmp
WHERE tmp.content_id = c.content_id AND c.content_id = 129
GROUP BY tmp.content_id HAVING MAX(tmp.version) = c.version
)
是什么导致我的交易中止?
I am doing an SQL transaction from kohana 3.2 framework in PHP with Postgresql 9.0
I get an exception
Database_Exception [ 0 ]: ERROR: current transaction is aborted,
commands ignored until end of transaction block [ SELECT c.* FROM
contents c WHERE c.content_id = 129 AND EXISTS( SELECT NULL FROM
contents tmp WHERE tmp.content_id = c.content_id AND c.content_id =
129 GROUP BY tmp.content_id HAVING MAX(tmp.version) = c.version ) ]
which i strange because this implies to me that some SQL prior to this one failed and thus no more SQL statements are being accepted. However I have all my SQL calls in a try/catch block and do a rollback on catch before rethrowing.
so i should never see this exception right?, Instead expect to see the one before, which would have spoiled the transaction to begin with...
I added logging to my PHP DB driver, and logged the following SQL statements leading up to the problem. The last SELECT statement below is the one referenced in my exception above.
The statement prior to the exception statement is an INSERT which would be a good candidate for the spoiler, however when i run all these statements by hand they all go thru properly.
UPDATE "articles"
SET article_id = 126, title = 'abc', blurb = 'abc article blurb'
WHERE "article_id" = 126
SELECT c.* FROM contents c
WHERE c.content_id = 127
AND EXISTS(
SELECT NULL FROM contents tmp
WHERE tmp.content_id = c.content_id AND c.content_id = 127
GROUP BY tmp.content_id HAVING MAX(tmp.version) = c.version
)
SELECT c.* FROM contents c
WHERE c.content_id = 128 AND EXISTS(
SELECT NULL FROM contents tmp
WHERE tmp.content_id = c.content_id AND c.content_id = 128
GROUP BY tmp.content_id HAVING MAX(tmp.version) = c.version
)
INSERT INTO "contents"
("blurb", "content", "content_id", "content_type_id", "title", "author_id", "version", "editor_id")
VALUES
('postit art', 'FEATURE_IMG_david-chan-drawing_IMG_0221.JPG', 128, 2, 'david chan drawing', 5, 2, 4)
SELECT c.* FROM contents c
WHERE c.content_id = 129 AND EXISTS(
SELECT NULL FROM contents tmp
WHERE tmp.content_id = c.content_id AND c.content_id = 129
GROUP BY tmp.content_id HAVING MAX(tmp.version) = c.version
)
what is causing my transaction to abort ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
PostgreSQL 服务器本身会记录事务中的错误以及导致错误的 SQL,这可能有助于提供线程的另一端来掌握?
如果数据库执行许多不同的任务,您可能需要定义一个
log_line_prefix
来帮助您选择客户端(例如log_line_prefix = '%t %c %q%u@% h:%d'
)The PostgreSQL server itself will log errors in transactions, along with the SQL that caused them, that might help provide another end of the thread to get hold of?
You might need to define a
log_line_prefix
to help you pick out your client if the database does a lot of different tasks (e.g. sth likelog_line_prefix = '%t %c %q%u@%h:%d '
)