Phalcon:交易和复杂模型

时间:2013-01-29 08:14:48

标签: model phalcon

在我的项目中,我有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

中显示的交易

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

e.g。

// 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实现方法,我在下面添加了它的代码,但它看起来像黑客,我也不想使用它:

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;
}

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

1 个答案:

答案 0 :(得分: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