为啥在循环结果集时无法启动事务?

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() 检索的错误;说:

不允许新事务,因为会话中还有其他线程在运行。

【讨论】:

以上是关于为啥在循环结果集时无法启动事务?的主要内容,如果未能解决你的问题,请参考以下文章

phpStudy启动后为啥MYSQL无法启动

为啥 spotifyd 守护程序无法启动

为啥 iOS7 模拟器无法启动或按预期启动...?

Android 简单应用无法启动不知道为啥

为啥copssh的安装后service无法启动

eclipse无法启动,为啥?