正しい対処法 Issuing rollback() due to DESTROY without explicit disconnect()
この Issuing rollback() due to DESTROY without explicit disconnect()
という警告を発しているのが DBI か DBD かまでは追ってないけど、掲題の通り Perl で MySQL にアクセスしていると「Issuing rollback() due to DESTROY without explicit disconnect()」という Warning に出会うことがある。
この warn は何か
Issuing rollback() due to DESTROY without explicit disconnect()
これは DBI の AutoCommit
オプションを 0 にしていると起こることがある。0 の意味は「AutoCommitしない」、つまり自分でトランザクションを管理します、ということになる。
で、この「Issuing rollback() due to DESTROY without explicit disconnect()」というエラーを google で検索すると、AutoCommitをオンにするか、Warnオプションで出力させなくするか、selectしただけのときも commit/rollback するという対処法が上位にでてくるが、どれもあまり適切ではない。
そもそも AutoCommit の設定をひっくり返せるならともかく、AutoCommit:0 にしている人は、そうしたくてしているわけなので、通常 AutoCommit を 1 にするという対応は難しい。また、Warnオプションを使ってWarnを抑制するのは、その他のWarnまで止めてしまう可能性があるのでやめた方が良い。また、updateしないでselectした時にも commit/rollback するというのは、副作用という意味ではあまり他に影響することはなさそうだが、トランザクションがネストするようなとき、意図しないタイミングで commit/rollback してしまうことがあるかもしれないので避けた方が良さそうだし、selectしかしていないのにそもそも毎度commit/rollbackなんて面倒くさくてやってられないですよね。
正しい対処法
というわけで、このwarnは、AutoCommit の設定によって発生するのと、エラーメッセージの先頭に Issuing rollback()
rollbackしたと書いているので、commit/rollbackすることに意識が向きがちだけど、エラーメッセージをちゃんと読むと以下のように書いてあって
due to DESTROY without explicit disconnect()
明示的に disconnect されないまま DBI/DBD オブジェクトが DESTROY されたよってことなのです。
つまり対処法としては、DBI/DBD オブジェクトが破棄される前に、ちゃんと disconnect せよ、ということになります。AutoCommit:0 を宣言して、トランザクションを利用するわけですから、接続と切断まできちんとハンドリングしないとダメだよ、という警告なわけです。というわけで、オブジェクトの破棄に任せて切断するのではなく、ちゃんと明示的に disconnect してあげれば警告はでなくなりますし、selectだけしたあとに commit/rollback はまったく必要ありません。
おわり。