QA@IT

スナップショット分離レベルは“結構特殊”??

3588 PV

「2014/10/08 19:19 スナップショット分離レベルは“結構特殊”?」で、
・行のバージョン管理を使用する READ COMMITTED 分離
・スナップショット分離
についてご回答いただき有り難うございました。

その上で申しますが、やはり、「スナップショット分離レベルは“結構特殊”」
というのは別の側面から考えて納得いきません。

考慮の前提としまして、
・前者も後者も、バージョン管理されたデータの読み取りの一貫性をステートメント
 レベルまたはトランザクションレベルで保証する
点で同じである以上、コスト(スナップショット分離によるペナルティー)が数倍に
なるとは思えないという点です。

その前提で、
・パーマネントなTmpテーブルにクエリを順次書き込み、それを読んで集計しては書き
 をするやり方
(複数人間が同時に使う事を担保するために自分が今やっているツールではTOMCATの
 session_idをTmpテーブルのキーの筆頭に据えています。)
を採用した場合、

スナップショット分離では、
・UNIONやJOINをむちゃくちゃ駆使して何とか1クエリで済ます配慮が要らず、
 単純なクエリを複数回行う事で目的が達成できる。
・単純なクエリの結果で有るが故に、クエリ結果を後から何回でも何十回でも再利用
 出来る。
・JOINをへたに使ったせいで、値が倍増してしまうなどの問題も、クエリ間でチェックを
 入れる事で対応が出来る。
利点が有ると思います。

パーマネントなTmpテーブルにクエリを順次書き込むやり方は、検証やテストに絶大な
効果を現します。(別にこのやり方は、銀行システムだけの専売特許とも思えません。)

本当に「スナップショット分離レベルは“結構特殊”」なのでしょうか??

  • 前者、後者というのは、それぞれ「READ_COMMITTED_SNAPSHOTがONの時のREAD COMMITTED分離レベル」と「SNAPSHOT分離レベル」の事ですか? -
  • gitkxxxbaseさんが今考えるところの「特殊」とはどういう所を指していますか?
    コストが高いとされている事ですか?
    スナップショット分離の実現しようとしている思想の部分ですか?
    実現方法の部分ですか?
    またはそれ以外?
    -
  • ↑(コストが高くないと思うから特殊ではないと考えておられるのか、スナップショット分離の考え方は利にかなっているから特殊でないと考えているのか、(tempdbに書き込むなどもうすこし実装寄りの)実現方法に違和感を感じないから特殊ではないと考えているのか…
    といった意味です。)
    -
  • flied_onionさんの3つのコメントの、1つめと2つめ+3つめですが、1つめはその通りです。2つめ+3つめですが、「特殊」とは、「技術的議論においてCOBOLや(部分的にも成功していませんが)PHPの様な、サムダウンの対象」「使ってはひんしゅくを買う対象」と思いました。コストが馬鹿高く無いなら理にかなったやり方の1つだと思います。 -
  • tempdbは杞憂では無いでしょうか?それに2014Ent.ならtempdbに置く行バージョン情報をメモリdbにキャッシュするやり方も出来たでしょうし。(自分が使っているのは2014Std.なので試せませんが。) -

回答

「結構特殊」って私が表現した「結構特殊」に関する疑問かと思ったのですが、違うのですね?
私が書いた「結構特殊」とは全く違う話をしているのですね?

というかあなた、READ_COMMITTED_SNAPSHOTでもステートメントレベルで一貫性があるなら「スナップショット分離はあまりにいらない子になりすぎる」から違うだろうみたいなことを言ってたんじゃなかったんですか…?
あれはなんだったんですか…?

以下、万一私が書いた「結構特殊」について納得いかないという話だったらですが…
いくらなんでも勝手に私の表現をゆがめないでください。
http://qa.atmarkit.co.jp/q/3858
http://qa.atmarkit.co.jp/q/3953
どこをどう見てサムダウンの対象とか使ってはひんしゅくを買う機能とか読んだのですか?
スナップショット分離を使うことを否定してすらいないのですが。
デフォルト的に常に使うものではなく、必要に応じて明示的に使うもの、使い分けるものと言っています。
理由があってそちらの方が向いているときちんと判断して使うならそれでいいんです。

スナップショット分離で、READ_COMMITTED_SNAPSHOTに対してデメリットとなるのは、コスト面というより、更新が競合する場合の同時実行性や、トランザクションが長くなるとかなり古いデータを使ったり、挿入されたデータがずっと見えないということがあるので、ロジック上それで問題がないか、などが大きいです。

更新が競合する状況では、トランザクションの中断が発生してやり直しということが起こります。
これが頻繁に発生するようでは向いていない可能性がありますし、逆に更新の競合など上で書いた問題点がなく、またロジック的に望ましい動作であるのなら、スナップショット分離が向いているでしょう。

って結局いろいろ書きましたが、なんかまた変にとられて反論されそうなので、ちょっと正直もうどうでもよくなってきてます。

編集 履歴 (2)
  • いらない子の件は自分の半可通のせいでした。この件は完全に理解したつもりです。後、スナップショット分離の件ですが、今修正しているツールでDBコネクションを所有しているクラスに、ReadCommitedとSnapshotIsolationを選択するメソッドを追加するよう提案したいと思います。(今は前者固定。ALLOWなんちゃらONは既に有り。) -
ウォッチ

この質問への回答やコメントをメールでお知らせします。