Database ZF2-更新多个表的数据库事务

Database ZF2-更新多个表的数据库事务,database,transactions,zend-framework2,Database,Transactions,Zend Framework2,我想使用ZF2 db事务更新多个表。 通常,我对单个表执行如下事务: $connection = null; try { $connection = $this->tableGateway->getAdapter()->getDriver()->getConnection(); $connection->beginTransaction(); $this->tableGateway->insert($d

我想使用ZF2 db事务更新多个表。 通常,我对单个表执行如下事务:

 $connection = null;
 try {
        $connection = $this->tableGateway->getAdapter()->getDriver()->getConnection();
        $connection->beginTransaction();
        $this->tableGateway->insert($data);
        $connection->commit();
     }
  catch (Exception $e) {
       if ($connection instanceof \Zend\Db\Adapter\Driver\ConnectionInterface) {
          $connection->rollback();
       }
  }

现在我想更新一个事务中的两个表。在ZF1中,我通过创建table2类的实例并在同一事务中调用其相应的方法来实现这一点。但是因为我不知道在模型中调用另一个模型类的方法,所以我不能像ZF1那样做。我需要这个来完成一个简单的任务,比如在tbl_发票中添加新行,以及在输入新账单(发票)时更新tbl_runno表的发票运行编号。

使用DataMapper设计模式。Pattern TableGateway用于将数据投影到单个表中

  • 您可以使用以下内容:

    使用示例:

    <?php  
    
    
    namespace ScContent\Mapper;
    
    use Zend\Db\Adapter\AdapterInterface;
    
    class ContentMapper extends AbstractDbMapper
    {
        /**
         * @var string
         */
        const ContentTableAlias = 'contentalias';
    
        /**
         * @var string
         */
        const UsersTableAlias = 'usersalias';
    
        /**
         * @param AdapterInterface $adapter
         */
        public function __construct(AdapterInterface $adapter) {
            $this->setAdapter($adapter);
        }
    
        /**
         * @var array
         */
        protected $_tables = array(
            self::ContentTableAlias => 'sc_content',
            self::UsersTableAlias   => 'sc_users'
        );
    
        /**
         * @param integer $id
         * @return null | array
         */
        public function findById($id)
        {
            $select = $this->getSql()->select()
                ->from(array('content' => $this->getTable(self::ContentTableAlias)))
                ->join(
                    array('users' => $this->getTable(self::UsersTableAlias)),
                    'content.author = users.user_id',
                    array('username'),
                    self::JoinInner
                )
                ->where(array('`content`.`id` = ?' => $id));
            return $this->execute($select)->current();
        }
    }
    

    在控制器中,您可以执行以下操作:

    $db = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
    $con = $db->getDriver()->getConnection();
    $con->beginTransaction();
    try {
        //get tables and do sth
        $con->commit();
    } catch (Exception $e) {
        $con->rollback();
    }
    

    谢谢你的回答。在上面给出的Akrabat链接中,方法(实体、映射器、服务3对象)与上面提供的示例代码略有不同。在ZfcUser module()中,他们使用了Akrabat的方法,但有点复杂。你认为ZfcUser的方法适合我吗?你必须理解映射器和网关之间的区别。映射器可以返回聚合和集合,以及集合中的每个项—它是一个单独的对象。映射器ZfcBase返回一个结果集,标准网关应该会这样做。如果网关提供了您想要的灵活性,那么您将接近ZfcBase AbstractDbMapper。
    $db = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
    $con = $db->getDriver()->getConnection();
    $con->beginTransaction();
    try {
        //get tables and do sth
        $con->commit();
    } catch (Exception $e) {
        $con->rollback();
    }