1

在我的项目中,我有一个entities表,所有实体都应该存在(以支持复杂的外键),所以我需要在特殊表(在这个实体列表中)中插入额外的行,然后再向我的模型表插入一行,我想问做这个的最好方式是什么。

因此,对于以下代码,我需要插入两行:在entity表中,然后为刚刚插入的行选取 id,将其保存在当前模型中并插入accounts表中:

$account = new Account();
$account->name = 'John';
$account->save(); // performs two inserts while creating model

据我了解,我可以使用 beforeCreate() 方法在entity表中插入行并为新创建的行获取 id,就像这样:

class Account
{
    public function beforeSave()
    {
        $entity = new \Entity();
        $entity->type = get_class($this);
        $entity->save();
        $this->id = $entity->id;
    }
}

但是这样,如果不插入帐户行,entity表中的行就会存在。

然后我想使用这里的文档中所示的事务http://docs.phalconphp.com/en/latest/reference/models.html#transactions

但我不明白,如果我为每个 model::create() 方法都有小事务,当我需要复杂操作的事务时它会如何工作?

例如

// controller action context
use Phalcon\Mvc\Model\Transaction\Manager as TxManager,
    Phalcon\Mvc\Model\Transaction\Failed as TxFailed;

try {

    //Create a transaction manager
    $manager = new TxManager();

    // Request a transaction
    $transaction = $manager->get();

    $account = new Account();
    $account->setTransaction($transaction);
    $account->name = "WALL·E";
    $account->created_at = date("Y-m-d");
    if ($account->save() == false) { // sub-transaction inside account::create() method
        $transaction->rollback("Cannot save account");
    }

    $accountPart = new AccountPart();
    $accountPart->setTransaction($transaction);
    $accountPart->type = "head";
    if ($accountPart->save() == false) { // sub-transaction inside accountPart::create() method
        $transaction->rollback("Cannot save account part");
    }

    //Everything goes fine, let's commit the transaction
    $transaction->commit();

} catch(TxFailed $e) {
    echo "Failed, reason: ", $e->getMessage();
}

很难想象它将如何在大型项目中工作。嵌套事务对数据库性能不是很好

我还考虑了 3d 实现方法,我在下面添加了它的代码,但它看起来像一个 hack,我也不想使用它:

public function create($data = null)
{   
    // Create abstract entity instance
    $entity = new \Entity();
    $entity->type = get_class($this);

    // Save abstract entity
    if (!$entity->save()) {
        return false;
    }

    // Save current entity
    $this->id = $entity->id;
    $result = parent::create($data);

    // Remove abstract entity if current row was not saved
    if (!$result) {
        $entity->delete();
    }

    return $result;
}

支持此类复杂实体的最佳且简单的方法是什么?

4

1 回答 1

2

实现事务的最简单方法是使用 0.9.0:

class Account
{
    public function beforeCreate()
    {
        $entity = new \Entity();
        $entity->type = get_class($this);
        $this->entity = $entity;
    }

    public function initialize()
    {
        $this->belongsTo(array('entity_id', 'Entity', 'id'));
    }

}

另一方面,事务管理器创建一个隔离连接,允许您查询在当前事务快照中修改的记录,以及查看未隔离的记录。

这里,在新文档中有对不同事务场景的解释:http: //docs.phalconphp.com/en/0.9.0/reference/models.html#transactions

于 2013-01-29T19:21:17.417 回答