1

私のプロジェクトentitiesには、(複雑な外部キーをサポートするために) すべてのエンティティが存在する必要があるテーブルがあるため、モデル テーブルに行を挿入する前に、特別なテーブル (このエンティティ リスト内) に追加の行を挿入する必要があります。これを行う最善の方法は何ですか。

したがって、次のコードでは、2 つの行を挿入する必要があります。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 メソッドについても考えました。以下のコードを追加しましたが、ハックのように見え、使用したくありません。

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 に答える