MT::Object::remove() でトランザクションが効かない件について
バグか仕様かわかりませんが嵌まったのでメモ。
- Movable Type 6
- MySQL 5.1 InnoDB
こんなかんじでトランザクション使えますが、remove()の場合、begin_workで立てたはずのトランザクションを使うぞ!的なフラグを無視しやがるようです。
MT::Object でのトランザクション(Rollback / Commit) - フリーエンジニアライフ
my $entry = MT->model( 'entry' )->load(); $entry->begin_work; $entry->remove(); # DELETE ... $entry->rollback(); # だが何度でもよみがえ…らない!
先の記事で触れたとおり、Data::ObjectDriver::BaseObject
のremove()
などを使っている限り、これでDELETE文の前に$driver->begin_work
でトランザクションが開始されるはずなのです。
lib/MT/Object.pm を覗いてみると、remove()についてはオーバーライドで親クラスをすっ飛ばしてました。
これでは$driver->begin_work
呼ばれません。
sub remove { my $obj = shift; my (@args) = @_; if ( !ref $obj ) { for my $which (qw( meta summary )) { my $meth = "remove_$which"; my $has = "has_$which"; $obj->$meth(@args) if $obj->$has; } $obj->remove_scores(@args) if $obj->isa('MT::Scorable'); MT->run_callbacks( $obj . '::pre_remove_multi', @args ); return $obj->driver->direct_remove( $obj, @args ); } else { return $obj->driver->remove( $obj, @args ); } }
回避方法ですが、とりあえずexists()
あたりを使っておけば動くようです。
my $entry = MT->model( 'entry' )->load(); $entry->begin_work; if ( $entry->exists() ) { # auto_commit=0 $entry->remove(); # DELETE ... $entry->rollback(); # rollback & auto_commit=1 }