Zend\Db在ZF2中如何控制事务?

19

ZF1 Zend_Db参考手册中有一个 完整的章节,介绍如何执行事务。

ZF2 Zend\Db参考手册 中没有关于事务的任何文档。

我如何在ZF2中执行事务?提供示例代码会很有帮助。

4个回答

41

你已经掌握了正确的开始、提交和回滚事务的方法,具体步骤如下:

$this->getAdapter()->getDriver()->getConnection()->beginTransaction();

$this->getAdapter()->getDriver()->getConnection()->commit();

$this->getAdapter()->getDriver()->getConnection()->rollback();

只是想强调一下,你也可以通过以下方式获取最后创建的ID:

$this->getAdapter()->getDriver()->getConnection()->getLastGeneratedValue()

如果你在使用pgSQL,你需要添加序列以返回最后创建的ID:

$this->getAdapter()->getDriver()->getConnection()->getLastGeneratedValue('mail_mailid_seq')

非常好,解释得很清楚,非常感谢!ZF2和ZF3的文档对这部分不是很清楚! - evilReiko
1
getAdapter()->getDriver()->getConnection() 是否会创建新的数据库连接? - Paiman Roointan

24

缺失的文档很奇怪。

为了找出发生了什么事,我不得不深入阅读Zend\Db\Adapter的API文档。

看起来 beginTransaction, rollbackcommitZend\Db\Adapter\Driver\ConnectionInterface 中定义。这意味着它们是在每个适配器连接上可调用的方法。不幸的是,连接本身相当难以找到。

我不确定的是——并且此时无法提供示例——找出实际调用这些方法的对象是哪个。最坏的情况是,看起来你可能想要调用 $adapter->getDriver()->getConnection()->beginTransaction()

噫。

我希望有更多知识和 ZF2 副本的其他人会看到这一点并提供更好的选择。

不要忘记,您可以自己发出 BEGIN TRANSACTION/ROLLBACK/COMMIT/SET autocommit=... SQL 语句。这可能是可以接受的,因为它看起来 Zend\Db 没有跟踪事务状态。


非常感谢Charles - 我需要仔细阅读API,关于您的最后一点,我是否可以通过PDO直接发出这些问题。 - Greg.Forbes

8

进行交易有两个要点:
1 - MyISAM不是一个事务性引擎,因此需要将表引擎更改为InnoDB。
2 - 事务查询("START TRANSACTION;""ROLLBACK;")连接必须与其他查询(插入或更新)相同。
在ZF2中执行此操作,您应该获取当前的数据库适配器并在所有查询中使用它。

这段代码将无法正确工作:

    $this->getAdapter()->getDriver()->getConnection()->beginTransaction();  
    //do some jobs - e.g : multiple tables update or insert.  
    $this->getAdapter()->getDriver()->getConnection()->rollback();   

由于 $this->getAdapter()->getDriver()->getConnection() 会创建新的数据库连接。

请改用以下代码:

    $connection = $this->getAdapter()->getDriver()->getConnection();
    $connection->beginTransaction();
    //do some jobs - e.g : multiple tables update or insert. 
    $connection->rollback();

如果你想检查你的连接是否正确,只需在mysql中启用查询日志。
运行查询后,你将在mysql日志中看到每个查询之前的连接号码。这些连接号码在所有事务查询中必须相同。


0

我在控制器中使用了beginTransactionrollbackcommit

在不需要控制事务的情况下,我对不同模型执行了许多事务,使用了预定义函数。

使用$this->getAdapter()->getDriver()->getConnection()->beginTransaction();会出现undefined getAdapter()方法的错误。

所以我采取了以下方式:

  //begain tarnsaction
                $db = Zend_Db_Table_Abstract::getDefaultAdapter();

                $db->beginTransaction();

//rollback

                $db->rollback();

//commit db changes

                $db->commit();

希望它能有用于解决问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接