MT::Objectでトランザクションを実装する
公開日 : 2017-04-06 12:17:01
Data::ObjectDriver::BaseObject::begin_work、rollback、commitを使う。
MTのコードにはこのあたりを考慮していないものが多すぎる。権限(Association)を割り当ててからユーザーのパーミッション(Permission)を更新する処理など、あちこちに投げっぱなしのコードがある。数万件のレコードを管理画面操作で更新する等。
複数のレコードを纏めてINSERT、UPDATEするなどの処理をループで回さなければならなかったり、速度面の問題であったり、あの忌まわしいMT::Meta::Proxy::save 問題であったり、そういうところにもっと目を向けて真摯に取り組まないと未来はないよ。
my @entries = MT->model( 'entry' )->load( undef, { sort => 'id', direction => 'descend' } );
my $driver = MT::Object->driver;
$driver->begin_work;
eval {
for my $obj ( @entries ) {
print $obj->id . "\n";
# if ( $obj->id < 800 ) {
# die; # ここでdieした時、すべてのレコードは更新されない
# }
$obj->excerpt( 'Hello World.' ); # 概要欄に値をセット
$obj->save or die $obj->errstr;
}
};
if( $@ ) {
$driver->rollback;
die $@;
}
$driver->commit;