你已经掌握了正确的开始、提交和回滚事务的方法,具体步骤如下:
$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')
缺失的文档很奇怪。
为了找出发生了什么事,我不得不深入阅读Zend\Db\Adapter的API文档。
看起来 beginTransaction
, rollback
和 commit
在 Zend\Db\Adapter\Driver\ConnectionInterface 中定义。这意味着它们是在每个适配器连接上可调用的方法。不幸的是,连接本身相当难以找到。
我不确定的是——并且此时无法提供示例——找出实际调用这些方法的对象是哪个。最坏的情况是,看起来你可能想要调用 $adapter->getDriver()->getConnection()->beginTransaction()
。
噫。
我希望有更多知识和 ZF2 副本的其他人会看到这一点并提供更好的选择。
不要忘记,您可以自己发出 BEGIN TRANSACTION
/ROLLBACK
/COMMIT
/SET autocommit=...
SQL 语句。这可能是可以接受的,因为它看起来 Zend\Db 没有跟踪事务状态。
进行交易有两个要点:
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日志中看到每个查询之前的连接号码。这些连接号码在所有事务查询中必须相同。
我在控制器中使用了beginTransaction
、rollback
和commit
。
在不需要控制事务的情况下,我对不同模型执行了许多事务,使用了预定义函数。
使用$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();
希望它能有用于解决问题。