是什么导致我的 SQL 事务在 php 没有注意到的情况下中止?

发布于 2024-11-28 18:34:58 字数 1769 浏览 0 评论 0原文

我正在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

你与昨日 2024-12-05 18:34:58

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 like log_line_prefix = '%t %c %q%u@%h:%d ')

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文