スポンサーリンク

DBの「トランザクション分離レベル」が必要な理由  (PostgreSQLで,ファントム・リードを防止すべきサンプル事例)
















PostgreSQL





トランザクション分離レベル










ANSI4


(一)READ UNCOMMITTED 

(二)READ COMMITTED

(三)REPEATABLE READ

(四)SERIALIZABLE



!! PostgreSQL vs MySQL 3
http://thinkit.co.jp/free/article/060...


  
http://itpro.nikkeibp.co.jp/article/C...


4ANSI

SQL Server



 


PostgreSQL2



1








2






 

1



3




(Dirty Reads) 





(Non-Repeatable Reads) 


2UPDATEDELETE


(Phantom Reads) 


2

 


3





http://www.interdb.jp/techinfo/postgr...


PostgreSQLOracle READ COMMITTEDSERIALIZABLE

DB24

2READ UNCOMMITTEDREPEATABLE READOracleDBMS

 






  • 「3つの現象」を防ぐために,「4つの分離レベル」がある。
  • PostgreSQLで利用できるのは「2つの分離レベル」であり,デフォルトは「リード・コミッティド」。

トランザクション分離レベルの設定コマンド


PostgreSQL





SHOW TRANSACTION ISOLATION LEVEL;









SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;



BEGIN;COMMIT;/ROLLBACK;




SET TRANSACTION
http://postgresql.jp/document/pg830do...


SHOW
http://www.commandprompt.com/ppbook/r...

 


Ruby on Rails
class MyModel < ActiveRecord::Base

  def self.hoge
    
    # 現在のトランザクション分離レベルを表示する
    p connection.execute("SHOW TRANSACTION ISOLATION LEVEL;")[0][0]
    
    # トランザクションを開始する(BEGIN)
    transaction do
      # トランザクション分離レベルをシリアライザブルに設定する
      connection.execute("SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;")

      # 現在のトランザクション分離レベルを表示する
      p connection.execute("SHOW TRANSACTION ISOLATION LEVEL;")[0][0]
      
      # トランザクションを終了する(COMMIT)
    end
    
    # 現在のトランザクション分離レベルを表示する
    p connection.execute("SHOW TRANSACTION ISOLATION LEVEL;")[0][0]
  end

end




[0][0]PGResultDB11




ruby script/console

>MyModel.hoge



"read committed"
"serializable"
"read committed"

serializable





分離レベルが低い場合に発生する不具合のサンプル


read comitted







1100

21




(一)1

(二)          2

(三)    

(四)               

(五)100   

(六)               

(七)

(八)               

(九)  

(十)       

(11)               

(12)         1

(13)               

(14)     

(15)               

(16)  

(17)               

(18)   

(19)               

(20)1        

(21)2

 


92

1010




1612

1011


10

1110


100

110






2


















練習問題



SERIALIZABLE



Rails





1010



21










 ActiveRecord::Base.allow_concurrency = true 



Ruby  Ruby on Rails
http://language-and-engineering.hatenablog.jp/entry/20101229/p1

結論


SERIALIZABLE

SERIALIZABLE









2or 使







DB





補足


使



http://www.fireproject.jp/feature/pos...


SERIALIZABLE,

Repeatable Read

SELECT FOR UPDATELOCK TABLE

 





1
http://d.hatena.ne.jp/masayang/201101...
  • 商売の世界なら「締め時間」があり、それ以前に受け付けたものなら処理の対象になる、というのが普通
  • 要するに,オンライン処理とバッチ処理がぶつかりはしないでしょ,という事