Hibernateは悲観的なロックと楽観的なロックコードの紹介を実現します

5430 ワード

4つの隔離メカニズムを忘れないでください.(1,2,4,8)
1.read-uncommitted:コミットされていないデータを読むことができる(汚れた読み取りを許可する存在)
2.read-committed:結果が読み出されるのは別のトランザクションのコミットのみですが、重複しない読み取りや幻の読み取りは発生しません.
4.repeatable read:MySQLデフォルト.繰り返し読むことができて、データを読んでからロックをかけて、他の人は先に更新しないで、私が使い終わったら更新します.あなたの事務が終わらないと、他の事務がこの記録を変更することはできません.
8.serializable:シーケンス化、最上位レベル.一つずつ来て、合併しない.効率が最も低い.
hibernateの隔離メカニズム
i.hibernate.connection.isolation=2
ii.悲観的なロックで解決:repeatable readの問題(データベースのロックに依存)
a)LockMode.Noneロックなしメカニズム、Transaction終了時、このモードに切り替わります
b)LockMode.readクエリー時にhibernateは自動的にロックを取得します
c)LockMode.write insert update hibernateは自動的にロックを取得します
d)以上の3中錠のパターンは、hibernate内部で使用されています
e)LockMode.UPGRADE_NOWAIT ORACLE対応ロック方式
例:
Account.java:

package com.bjsxt.hibernate; 
import javax.persistence.Entity; 
import javax.persistence.GeneratedValue; 
import javax.persistence.Id; 
@Entity 
public class Account { 
private int id; 
private int balance; //BigDecimal 
@Id 
@GeneratedValue 
public int getId() { 
return id; 
} 
public void setId(int id) { 
this.id = id; 
} 
public int getBalance() { 
return balance; 
} 
public void setBalance(int balance) { 
this.balance = balance; 
} 
} 

hibernate.cfg.xmlでの構成:

 

テスト:

@Test 
public void testSave() { 
Session session = sf.openSession(); 
session.beginTransaction(); 
Account a = new Account(); 
a.setBalance(100); 
session.save(a); 
session.getTransaction().commit(); 
session.close(); 
} 
@Test 
public void testOperation1() { 
Session session = sf.openSession(); 
session.beginTransaction(); 
Account a = (Account)session.load(Account.class, 1); 
int balance = a.getBalance(); 
//do some caculations 
balance = balance - 10; 
//                       
//       " "          
a.setBalance(balance); 
session.getTransaction().commit(); 
session.close(); 
} 
//                  
@Test 
public void testPessimisticLock() { 
Session session = sf.openSession(); 
session.beginTransaction(); 
//     ,             
Account a = (Account)session.load(Account.class, 1, LockMode.UPGRADE); 
int balance = a.getBalance(); 
//do some caculation 
balance = balance - 10; 
a.setBalance(balance); 
session.getTransaction().commit(); 
session.close(); 
} 

これはデータベースのロックに依存しています.つまり、データベースにロックを追加するように命令します.――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
iii.Hibernate(JPA)楽観ロック(ReadCommitted)
これはデータベースに依存してロックされているのではなく、プログラムにロックされています.
例を挙げると、データは分離メカニズム(繰り返し読むことができない)が必要で、このとき更新されたフィールドに「バージョン番号」(versionフィールド)を付け、updateを与える人がいると、この値は1(version+1)を加えます.
では、このメカニズムはどのように隔離能力を生み出すのでしょうか.
なぜなら、トランザクションAがフィールドを読み出すと同時に、トランザクションBもこのフィールドを読み出し、それを変更するとversionが1になるからです.このときトランザクションAは、フィールドが変更されたかどうかをチェックし、変更された場合もそれに応じて変更され、変更されなければ変更されません.
楽観ロックの実装:(@Version)
Account.java:

package com.bjsxt.hibernate;  
import javax.persistence.Entity; 
import javax.persistence.GeneratedValue; 
import javax.persistence.Id; 
import javax.persistence.Version;  
@Entity 
public class Account { 
private int id; 
private int balance; 
private int version;  
@Version//                       
public int getVersion() { 
return version; 
} 
public void setVersion(int version) { 
this.version = version; 
} 
@Id 
@GeneratedValue 
public int getId() { 
return id; 
} 
public void setId(int id) { 
this.id = id; 
} 
public int getBalance() { 
return balance; 
} 
public void setBalance(int balance) { 
this.balance = balance; 
} 
} 

テスト:

 @Test 
public void testSave() { 
Session session = sf.openSession(); 
session.beginTransaction(); 
Account a = new Account(); 
a.setBalance(100); 
session.save(a); 
session.getTransaction().commit(); 
session.close(); 
} 
@Test 
public void testOptimisticLock() { 
Session session = sf.openSession(); 
Session session2 = sf.openSession(); 
session.beginTransaction(); 
Account a1 = (Account) session.load(Account.class, 1); 
session2.beginTransaction(); 
Account a2 = (Account) session2.load(Account.class, 1); 
a1.setBalance(900); 
a2.setBalance(1100); 
//   session    ,version  +1 
session.getTransaction().commit(); 
System.out.println(a1.getVersion()); 
//   session     ,  version        
//        ,     (        ) 
        session2.getTransaction().commit(); 
System.out.println(a2.getVersion()); 
session.close(); 
session2.close(); 
} 

悲観的で楽観的な違い:悲観的なロックは必ず影響を受けると思って、私はロックをかけて誰も動こうとしないでください.楽観的にロックして、何も起こらなければいいので、何かあったら何とかします.
まとめ
以上,Hibernateが悲観的ロックと楽観的ロックコードを実現することについて紹介したすべての内容であり,hibernateの学習に役立つことを期待する.何か問題があったらいつでも伝言を残して、編集者はすぐにみんなに返事します.皆様のご支援に感謝いたします.