在我的项目中,我有一个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;
}
支持此类复杂实体的最佳且简单的方法是什么?