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

时间:2013-08-10 01:07:36

标签: database transactions zend-framework2

我想使用ZF2 db transaction来更新多个表。 通常情况下,我会通过类似的方式对单个表进行交易:

 $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_invoice添加新行并更新tbl_runno表的发票运行编号。

2 个答案:

答案 0 :(得分:3)

在您的控制器中,您可以:

$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();
}

答案 1 :(得分:0)

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

  • http://akrabat.com/development/objects-in-the-model-layer
  • http://akrabat.com/php/objects-in-the-model-layer-part-2
  • http://www.slideshare.net/aaronsaray/midwest-php-2013
  • https://leanpub.com/zendframework2-en 你可以使用这样的东西:

    namespace ScContent\Mapper;
    
    use Zend\Db\Sql\Sql;
    use Zend\Db\Sql\Select;
    use Zend\Db\Sql\SqlInterface;
    use Zend\Db\Sql\PreparableSqlInterface;
    
    use Zend\Db\Adapter\AdapterInterface;
    use Zend\Db\Adapter\Driver\ResultInterface;
    
    use Zend\Stdlib\Hydrator\ClassMethods;
    use Zend\StdLib\Hydrator\HydratorInterface;
    
    abstract class AbstractDbMapper
    {
        /**
         * @var string
         */
        const JoinInner = Select::JOIN_INNER;
    
        /**
         * @var string
         */
        const JoinLeft = Select::JOIN_LEFT;
    
        /**
         * @var string
         */
        const JoinRight = Select::JOIN_RIGHT;
    
        /**
         * @var Zend\Db\Adapter\AdapterInterface
         */
        protected $_adapter;
    
        /**
         * @var Zend\Db\Sql\SqlInterface
         */
        protected $_sql;
    
        /**
         * @var Zend\Stdlib\HydratorInterface
         */
        protected $_hydrator;
    
        /**
         * @var array
         */
        protected $_tables = array();
    
        /**
         * @param Zend\Db\Adapter\AdapterInterface $adapter
         */
        public function setAdapter(AdapterInterface $adapter)
        {
            $this->_adapter = $adapter;
        }
    
        /**
         * @return Zend\Db\Adapter\AdapterInterface
         */
        public function getAdapter()
        {
            if(!$this->_adapter instanceof AdapterInterface) {
                throw new Exception('Adapter is not installed.');
            }
            return $this->_adapter;
        }
    
        /**
         * @param Zend\Db\Sql\SqlInterface $sql
         */
        public function setSql(SqlInterface $sql)
        {
            $this->_sql = $sql;
        }
    
        /**
         * @return Zend\Db\Sql\SqlInterface
         */
        public function getSql()
        {
            if(!$this->_sql instanceof SqlInterface) {
                $this->_sql = new Sql($this->getAdapter());
            }
            return $this->_sql;
        }
    
        /**
         * @param Zend\Stdlib\HydratorInterface $hydrator
         */
        public function setHydrator(HydratorInterface $hydrator)
        {
            $this->_hydrator = $hydrator;
        }
    
        /**
         * @return Zend\Stdlib\HydratorInterface
         */
        public function getHydrator()
        {
            if(!$this->_hydrator instanceof HydratorInterface) {
                $this->_hydrator = new ClassMethods();
            }
            return $this->_hydrator;
        }
    
        /**
         * @param string $alias
         * @param string $name
         */
        public function setTable($alias, $name)
        {
            $this->_tables[$alias] = $name;
        }
    
        /**
         * @param string $alias
         * @throws Exception
         * @return string
         */
        public function getTable($alias)
        {
            if(!array_key_exists($alias, $this->_tables)) {
                throw new Exception(sprintf("Unknown table alias '%s'.", $alias));
            }
            return $this->_tables[$alias];
        }
    
        /**
         * @return int|null|false
         */
        protected function lastInsertId()
        {
            return $this->adapter->getDriver()->getConnection()->getLastGeneratedValue();
        }
    
        /**
         * @param void
         * @return void
         */
        protected function beginTransaction()
        {
            $this->getAdapter()->getDriver()->getConnection()->beginTransaction();
        }
    
        /**
         * @param void
         * @return void
         */
        protected function commit()
        {
            $this->getAdapter()->getDriver()->getConnection()->commit();
        }
    
        /**
         * @return bool
         */
        protected function inTransaction()
        {
            return $this->getAdapter()->getDriver()
                ->getConnection()->getResource()->inTransaction();
        }
    
        /**
         * @param void
         * @return void
         */
        protected function rollBack()
        {
            $this->getAdapter()->getDriver()->getConnection()->rollBack();
        }
    
        /**
         * @param Zend\Db\Sql\PreparableSqlInterface $sqlObject
         * @return Zend\Db\Adapter\ResultInterface
         */
        protected function execute(PreparableSqlInterface $sqlObject)
        {
            return $this->getSql()->prepareStatementForSqlObject($sqlObject)->execute();
        }
    
        /**
         * @param Zend\Db\Adapter\ResultInterface $source
         * @return array
         */
        protected function toArray(ResultInterface $source)
        {
            $result = array();
            foreach($source as $item) {
                $result[] = $item;
            }
            return $result;
        }
    
        /**
         *
         */
        protected function toString(SqlInterface $sqlObject)
        {
            return $this->getSql()->getSqlStringForSqlObject($sqlObject);
        }
    }
    

    使用示例:

    <?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();
        }
    }