为啥在循环结果集时无法启动事务?
Posted
技术标签:
【中文标题】为啥在循环结果集时无法启动事务?【英文标题】:Why can't I start a transaction while looping a result set?为什么在循环结果集时无法启动事务? 【发布时间】:2016-03-24 15:03:50 【问题描述】:我有以下 PDO 代码(php 5.6,Microsoft SQL Server 2014):
$st = $db->prepare('SELECT TOP 5 * FROM table');
$st->execute();
while ($st->fetch())
var_dump($db->beginTransaction());
//$db->rollback();
结果如下:
bool(false)
bool(false)
bool(false)
bool(false)
bool(true)
我期待所有真实的结果,但直到检索到最后一条记录才开始事务。为什么在循环结果集时无法启动事务?
打开或关闭MARS 似乎没有任何效果。
【问题讨论】:
阅读文档好像有一种模式可以切换,好像是先等到完成。也许尝试打开自动提交模式。 php.net/manual/en/pdo.begintransaction.php 为什么要在每次循环迭代时启动事务? 背景:需要为结果集中的每一行操作几个表(“操作”),并希望将其包装在事务中,以便每个操作能够回滚一个错误操作和仍继续其他操作。 好吧,那么这里有一个预感为什么(我不使用 MSSQL,所以我不会发布答案)。这是因为您使用的是while($sth->fetch())
。在遍历完成之前,光标不会“释放”,这就是为什么它适用于最后一条记录而不是以前的记录。我会改用$records = $sth->fetchAll(); foreach($records as $record) .....
并尝试使用它。
【参考方案1】:
只要游标处于打开状态,就不能在使用 MSSQL 时启动新事务。在结果集上调用 closeCursor() 或检索使用查询返回的所有结果会释放该游标并再次允许事务。
还有; beginTransaction() 返回 false 也会产生可以使用 errorInfo() 检索的错误;说:
不允许新事务,因为会话中还有其他线程在运行。
【讨论】:
以上是关于为啥在循环结果集时无法启动事务?的主要内容,如果未能解决你的问题,请参考以下文章