save() 時のトランザクション状態確認
- CakePHP 3.5.4 で確認
beforeSave()、afterSave()、afterSaveCommit()で、トランザクションの状態を確認して見た。
結果
1 がトランザクション中、0はトランザクション外。
コールバック | begin()なし | beginあり | transactional() |
---|---|---|---|
beforesave() | 1 | 1 | 1 |
aftersave() | 1 | 1 | 1 |
afteraveCommit() | 0 | - | - |
自前でトランザクションを開始するしないに関わらず、beforeSave(),afterSave()はsave()からのトランザクションになる。
afterSaveCommit()はドキュメントの通り、save()実行前にトランザクション開始されてたら呼ばれない。
Connection::commit() コミットしても呼ばれない。
参考:テストコード
table.php
public function beforeSave(\Cake\Event\Event $event, \Cake\Datasource\EntityInterface $entity, \ArrayObject $options)
{
debug('beforeSave():' . $this->getConnection()->inTransaction());
}
public function afterSave(\Cake\Event\Event $event, \Cake\Datasource\EntityInterface $entity, \ArrayObject $options)
{
debug('afterSave():' . $this->getConnection()->inTransaction());
}
public function afterSaveCommit(\Cake\Event\Event $event, \Cake\Datasource\EntityInterface $entity, \ArrayObject $options)
{
debug('afterSaveCommit():' . $this->getConnection()->inTransaction());
}
test.php
public function testSave1()
{
echo '-------- save ---------' . PHP_EOL;
$ad = $this->Users->newEntity();
$ad->name = 'no-tran';
$this->Users->save($ad);
}
public function testSave2()
{
echo '---------- save in Tran --------' . PHP_EOL;
$ad = $this->Users->newEntity();
$ad->name = 'in-tran';
$this->Users->getConnection()->begin();
$this->Users->save($ad);
$this->Users->getConnection()->commit();
}
public function testSave3()
{
echo '----------- transactional() ---------' . PHP_EOL;
$this->Users->getConnection()->transactional(function($conn) {
$ad = $this->Users->newEntity();
$ad->name = 'transactional()';
$this->Users->save($ad);
});
}