SlideShare a Scribd company logo
1 of 85
Download to read offline
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 1
JJUG CCC 2014 Spring
Java EE 7対応!
JPAの同時実行制御とロック
2014/05/18
(株)ウチダ人材開発センタ 多田真敏
このセッションについて
Twitterハッシュタグ : #ccc_r15
JPAの同時実行制御とロックについて、基礎から
詳しく説明します
同時実行制御とロックにおいて、JPA実装と
DBMSを変えたときの、挙動の違いや注意点を
説明します
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 2
アジェンダ
まずは自己紹介
同時実行制御とロックとは?
JPAにおける同時実行制御とロック
今回のサンプルプログラム
EclipseLink×MySQLの場合
EclipseLink×PostgreSQLの場合
Hibernate×MySQLの場合
Hibernate×PostgreSQLの場合
まとめ
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 3
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 4
まずは自己紹介
あんた、誰?
IT研修インストラクター、
社会人7年目。三十路。
専門はJava、.NET、ネット
ワーク、業務知識など。
中小企業診断士、SJC-
WC、応用情報技術者。
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 5
Twitter・ブログ
Twitter : @suke_masa
ブログ : Java EE 事始め!
http://masatoshitada.hatenadiary.jp/
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 6
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 7
同時実行制御とロックとは?
ロックとは?
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 8
empno ename sal
101 Nishida 500000
102 Nohira 285000
103 Kiyama 245000
T1 T2
複数のトランザクションから同時に実行された
とき、データの不整合が起こらないように行・表
・DBにロックをかける、DBMSの機能
○ ×
ロックなしの場合に起こる不整合
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 9
empno ename sal
101 Nishida 500000
102 Nohira 285000
103 Kiyama 245000
本当は520000
にならないと
おかしい!
2つのトランザクションか
ら同時に、empno=101
のsalを10000プラスする
① T1:101のsalを検索
(500000)
② T2:101のsalを検索
(500000)
③ T1:salを①+10000に更
新(510000)
④ T2:salを②+10000に更
新(510000)
READロックとWRITEロック
① READロック(共有ロック)
他のトランザクションはREADロックは取得できるが
、WRITEロックは取得できない
② WRITEロック(占有ロック、排他ロック)
他のトランザクションはREADロックもWRITEロック
も取得できない
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 10
先のトランザクション
READロック WRITEロック
後のトランザ
クション
READロック ○ ×
WRITEロック × ×
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 11
JPAにおける
同時実行制御とロック
楽観的ロックと悲観的ロック
楽観的ロック(OPTIMISTIC)
更新対象の行に対して、他のトランザクションからの更新
は無いという前提に立つ
パフォーマンスは悲観的ロックと比較して高い
悲観的ロック(PESSIMISTIC)
更新対象の行に対してロックをかけ、他のトランザクショ
ンからの更新をDBMSが防ぐ
パフォーマンスは楽観的ロックと比較して低い
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 12
楽観的ロック → DBMSのロック機能を利用しない
悲観的ロック → DBMSのロック機能を利用する
バージョニング
「バージョン」を表す列を対象テーブルに追加
エンティティのバージョンフィールドには@Version
アノテーションを付加
バージョンの型はint(Integer)、short(Short)、long
(Long)、java.sql.Timestampが使用可能
更新時にバージョンの値が更新(インクリメントなど
)される
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 13
LockModeType
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 14
ロックモード 説明
OPTIMISTIC 楽観的ロック
OPTIMISTIC_FORCE_
INCREMENT
楽観的ロック。バージョンの値をインクリメ
ントする
PESSIMISTIC_READ 悲観的ロック。READロックを取得する
PESSIMISTIC_WRITE 悲観的ロック。WRITEロックを取得する
PESSIMISTIC_FORCE
_INCREMENT
悲観的ロック。WRITEロックを取得し、
バージョンの値をインクリメントする
NONE ロックしない(デフォルト)
※READ・WRITEは非推奨
LockModeTypeの指定方法
EntityManagerインターフェイス
<T> T find(Class<T> entityClass, Object
primaryKey, LockModeType lockMode)
void lock(Object entity, LockModeType lockMode)
void refresh(Object entity, LockModeType lockMode)
Query(TypedQuery)インターフェイス
Query setLockMode(LockModeType lockMode)
NamedQueryアノテーション
lockmode属性
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 15
金魚本では・・・
「4.5 同時実行」は6ページしかない
悲観的ロックについては0.5ページ程度
Java EE 5までは楽観的ロックしかなかった
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 16
参考資料
Java EE 7 Tutorial
42. Controlling Concurrent Access to
Entity Data With Rocking
JSR-338 Java Persistence 2.1
3.4 Locking and Concurrency
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 17
SPECIAL THANKS!!
O社認定講師&データベーススペシャリストの
Y部長
外語大卒の後輩Kちゃん
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 18
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 19
今回のサンプルプログラム
実験環境
JPA実装
EclipseLink 2.5.2-M1
Hibernate Entity Manager 4.3.1.Final
DBMS
PostgreSQL 8.4.19
MySQL 5.6.16
その他
Windows 7 SP1(x64)
JDK 7u45
Eclipse 4.3.1
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 20
2×2
=4通り
使用するテーブル
empno(PK) ename sal version
101 Nishida 500000 1
102 Nohira 285000 1
103 Kiyama 245000 1
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 21
emp2
empno=101のレコードを検索後、
そのレコードのsalを10000プラスする処理を、
2スレッドから同時実行
バージョン列
エンティティクラス
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 22
@Entity
public class Emp2 implements Serializable {
@Id
private Integer empno;
private String ename;
private Integer sal;
@Version
private Integer version;
// setter/getter, equals(), hashCode(), toString()
}
version列と
対応するフィールド
スレッドクラス
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 23
public class UpdateThread extends Thread {
@Override
public void run() {
String threadName = Thread.currentThread().getName();
EntityManagerFactory factory =
Persistence.createEntityManagerFactory("emp");
EntityManager manager = factory.createEntityManager();
EntityTransaction tx = manager.getTransaction();
tx.begin();
Emp2 emp = manager.find(Emp2.class, 101, LockModeType.NONE);
int sal = emp.getSal();
System.out.println(threadName + " 検索直後 " + emp);
try {
Thread.sleep(1000);
} catch (InterruptedException e) { e.printStackTrace(); }
ここでLockModeType
を指定
スレッドクラス
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 24
try {
emp.setSal(sal + 10000);
System.out.println(threadName + " flush直前 " + emp);
manager.flush();
System.out.println(threadName + " flush直後 " + emp);
tx.commit();
System.out.println(threadName + " commit.");
System.out.println(threadName + " commit直後 " + emp);
} catch (Exception e) {
System.out.println(threadName
+ " 例外発生:" + e.getClass().getName());
e.printStackTrace();
tx.rollback();
System.out.println(threadName + " rollback.");
}
スレッドクラス
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 25
System.out.println(threadName + " 終了 " + emp);
manager.close();
factory.close();
}
}
メインクラス
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 26
public class Main {
public static void main(String[] args) {
Thread thread1 = new UpdateThread();
thread1.setName("T1");
Thread thread2 = new UpdateThread();
thread2.setName("T2");
thread1.start();
thread2.start();
}
}
マルチスレッドで
同時実行
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 27
EclipseLink×MySQLの場合
NONE
ロックしない(デフォルト)
バージョニングは不要なので、@Versionをコメン
トアウト
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 28
@Entity
public class Emp2 implements Serializable {
・・・
// @Version コメントアウト
private Integer version;
・・・
}
NONEの実行ログ
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 29
[EL Fine]: sql: SELECT EMPNO, ENAME, SAL, VERSION FROM EMP2 WHERE (EMPNO = ?)
bind => [101]
[EL Fine]: sql: SELECT EMPNO, ENAME, SAL, VERSION FROM EMP2 WHERE (EMPNO = ?)
bind => [101]
T1 検索直後 Emp2 [empno=101, ename=Nishida, sal=500000, version=1]
T2 検索直後 Emp2 [empno=101, ename=Nishida, sal=500000, version=1]
T1 flush直前 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T2 flush直前 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
[EL Fine]: sql: UPDATE EMP2 SET SAL = ? WHERE (EMPNO = ?) bind => [510000, 101]
[EL Fine]: sql: UPDATE EMP2 SET SAL = ? WHERE (EMPNO = ?) bind => [510000, 101]
T1 flush直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T2 flush直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T1 commit.
T1 commit直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T1 終了 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T2 commit.
T2 commit直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T2 終了 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
実行の様子
① T1が検索→sal=500000
② T2が検索→sal=500000
③ T1がsal=500000+10000で更新
④ T2がsal=500000+10000で更新
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 30
salは最終的に510000になる
OPTIMISTIC
楽観的ロック
バージョニング必須
バージョンが無い場合はPersistenceException
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 31
@Entity
public class Emp2 implements Serializable {
・・・
@Version // 必須
private Integer version;
・・・
}
OPTIMISTICの実行ログ
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 32
[EL Fine]: sql: SELECT EMPNO, ENAME, SAL, VERSION FROM EMP2 WHERE (EMPNO = ?)
bind => [101]
[EL Fine]: sql: SELECT EMPNO, ENAME, SAL, VERSION FROM EMP2 WHERE (EMPNO = ?)
bind => [101]
T2 検索直後 Emp2 [empno=101, ename=Nishida, sal=500000, version=1]
T1 検索直後 Emp2 [empno=101, ename=Nishida, sal=500000, version=1]
T1 flush直前 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T2 flush直前 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
[EL Fine]: sql: UPDATE EMP2 SET SAL = ?, VERSION = ? WHERE ((EMPNO = ?) AND
(VERSION = ?)) bind => [510000, 2, 101, 1]
[EL Fine]: sql: UPDATE EMP2 SET SAL = ?, VERSION = ? WHERE ((EMPNO = ?) AND
(VERSION = ?)) bind => [510000, 2, 101, 1]
T1 flush直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=2]
T1 commit.
T1 commit直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=2]
T1 終了 Emp2 [empno=101, ename=Nishida, sal=510000, version=2]
T2 例外発生:javax.persistence.OptimisticLockException
T2 rollback.
T2 終了 Emp2 [empno=101, ename=Nishida, sal=510000, version=2]
(以下、スタックトレース)
実行の様子
① T1が検索→sal=500000, version=1
② T2が検索→sal=500000, version=1
③ T1がsal=500000+10000, version=1+1
で更新→コミット
④ T2がsal=500000+10000, version=1+1
で更新
→バージョンの値が既に変更されているため、
OptimisticLockExceptionが発生してロー
ルバック
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 33
実行後のバージョン値
ロールバックされたエンティティも、バージョン値
がインクリメントされる
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 34
T1 commit.
T1 commit直後 Emp2 [empno=101, ename=Nishida,
sal=510000, version=2]
T1 終了 Emp2 [empno=101, ename=Nishida, sal=510000,
version=2]
T2 例外発生:javax.persistence.OptimisticLockException
T2 rollback.
T2 終了 Emp2 [empno=101, ename=Nishida, sal=510000,
version=2]
バージョン値変更の検知方法
UPDATE文のWHERE句に主キーとバージョン列
を指定している
→バージョン値が既に変更されていた場合、
更新行数はゼロになる
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 35
[EL Fine]: sql: UPDATE EMP2 SET SAL = ?, VERSION = ?
WHERE ((EMPNO = ?) AND (VERSION = ?))
bind => [510000, 2, 101, 1]
OPTIMISTIC_FORCE_INCREMENT
楽観的ロック。バージョン値を強制的にインクリメ
ントする
バージョニング必須
EclipseLinkの場合、挙動はOPTIMISTICと全く
同じ
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 36
OPTIMISTIC_FORCE_INCREMENTの実行ログ
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 37
[EL Fine]: sql: SELECT EMPNO, ENAME, SAL, VERSION FROM EMP2 WHERE (EMPNO = ?)
bind => [101]
T2 検索直後 Emp2 [empno=101, ename=Nishida, sal=500000, version=1]
T1 検索直後 Emp2 [empno=101, ename=Nishida, sal=500000, version=1]
T2 flush直前 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T1 flush直前 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
[EL Fine]: sql: UPDATE EMP2 SET SAL = ?, VERSION = ? WHERE ((EMPNO = ?) AND
(VERSION = ?)) bind => [510000, 2, 101, 1]
T2 flush直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=2]
[EL Fine]: sql: UPDATE EMP2 SET SAL = ?, VERSION = ? WHERE ((EMPNO = ?) AND
(VERSION = ?)) bind => [510000, 2, 101, 1]
T2 commit.
T2 commit直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=2]
T2 終了 Emp2 [empno=101, ename=Nishida, sal=510000, version=2]
T1 例外発生:javax.persistence.OptimisticLockException
T1 rollback.
T1 終了 Emp2 [empno=101, ename=Nishida, sal=510000, version=2]
PESSIMISTIC_READ
悲観的ロック。READロックを取得
→EclipseLinkではSELECT FOR UPDATE文が
実行され、WRITEロックを取得する
バージョニング不要
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 38
@Entity
public class Emp2 implements Serializable {
・・・
// @Version コメントアウト
private Integer version;
・・・
}
PESSIMISTIC_READの実行ログ
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 39
[EL Fine]: sql: SELECT EMPNO, ENAME, SAL, VERSION FROM EMP2 WHERE (EMPNO = ?)
FOR UPDATE bind => [101]
[EL Fine]: sql: SELECT EMPNO, ENAME, SAL, VERSION FROM EMP2 WHERE (EMPNO = ?)
FOR UPDATE bind => [101]
T1 検索直後 Emp2 [empno=101, ename=Nishida, sal=500000, version=1]
T1 flush直前 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
[EL Fine]: sql: UPDATE EMP2 SET SAL = ? WHERE (EMPNO = ?) bind => [510000, 101]
T1 flush直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T1 commit.
T1 commit直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T1 終了 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T2 検索直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T2 flush直前 Emp2 [empno=101, ename=Nishida, sal=520000, version=1]
[EL Fine]: sql: UPDATE EMP2 SET SAL = ? WHERE (EMPNO = ?) bind => [520000, 101]
T2 flush直後 Emp2 [empno=101, ename=Nishida, sal=520000, version=1]
T2 commit.
T2 commit直後 Emp2 [empno=101, ename=Nishida, sal=520000, version=1]
T2 終了 Emp2 [empno=101, ename=Nishida, sal=520000, version=1]
実行の様子
① T1が検索、WRTIEロックを取得
→sal=500000
② T2が検索しようとするが、T1がWRITEロックを取
得しているので、DB内の待ち行列に入る
③ T1がsal=500000+10000で更新
→コミットしたらロック解放
④ T2が待ち行列から出て検索、WRITEロックを取得
→sal=510000
⑤ T2がsal=510000+10000で更新
→コミットしたらロック解放
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 40
SQLログと実際の実行順序は違う
SQLログは、JPAがDBMSに発行した「つもり」の
SQLが表示される
実際には、発行されてもDBMS内の待ち行列に
入っている場合がある
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 41
[EL Fine]: sql: SELECT EMPNO, ENAME, SAL, VERSION FROM EMP2
WHERE (EMPNO = ?) FOR UPDATE bind => [101]
[EL Fine]: sql: SELECT EMPNO, ENAME, SAL, VERSION FROM EMP2
WHERE (EMPNO = ?) FOR UPDATE bind => [101]
T1 検索直後 Emp2 [empno=101, ename=Nishida, sal=500000, version=1]
・・・
T1 終了 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T2 検索直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
・・・
PESSIMISTIC_WRITE
悲観的ロック。WRITEロックを取得
→EclipseLinkではPESSIMISTIC_READと
挙動は同じ
バージョニング不要
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 42
PESSIMISTIC_WRITEの実行ログ
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 43
[EL Fine]: sql: SELECT EMPNO, ENAME, SAL, VERSION FROM EMP2 WHERE (EMPNO = ?)
FOR UPDATE bind => [101]
T2 検索直後 Emp2 [empno=101, ename=Nishida, sal=500000, version=1]
[EL Fine]: sql: SELECT EMPNO, ENAME, SAL, VERSION FROM EMP2 WHERE (EMPNO = ?)
FOR UPDATE bind => [101]
T2 flush直前 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
[EL Fine]: sql: UPDATE EMP2 SET SAL = ? WHERE (EMPNO = ?) bind => [510000, 101]
T2 flush直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T1 検索直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T2 commit.
T2 commit直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T2 終了 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T1 flush直前 Emp2 [empno=101, ename=Nishida, sal=520000, version=1]
[EL Fine]: sql: UPDATE EMP2 SET SAL = ? WHERE (EMPNO = ?) bind => [520000, 101]
T1 flush直後 Emp2 [empno=101, ename=Nishida, sal=520000, version=1]
T1 commit.
T1 commit直後 Emp2 [empno=101, ename=Nishida, sal=520000, version=1]
T1 終了 Emp2 [empno=101, ename=Nishida, sal=520000, version=1]
PESSIMISTIC_FORCE_INCREMENT
悲観的ロック。バージョン値を強制的にインクリメ
ントする
チュートリアルにはWRITEロックかREADロック
か記述されていない
→JSRには「exclusive lock(=WRITEロック)」
と書いてある
バージョニング必須
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 44
PESSIMISTIC_FORCE_INCREMENTの実行ログ
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 45
[EL Fine]: sql:SELECT EMPNO, ENAME, SAL, VERSION FROM EMP2 WHERE (EMPNO = ?) FOR
UPDATE bind => [101]
[EL Fine]: sql: SELECT EMPNO, ENAME, SAL, VERSION FROM EMP2 WHERE (EMPNO = ?)
FOR UPDATE bind => [101]
T1 検索直後 Emp2 [empno=101, ename=Nishida, sal=500000, version=1]
T1 flush直前 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
[EL Fine]: sql: UPDATE EMP2 SET SAL = ?, VERSION = ? WHERE ((EMPNO = ?) AND
(VERSION = ?)) bind => [510000, 2, 101, 1]
T1 flush直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=2]
T2 検索直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=2]
T1 commit.
T1 commit直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=2]
T1 終了 Emp2 [empno=101, ename=Nishida, sal=510000, version=2]
T2 flush直前 Emp2 [empno=101, ename=Nishida, sal=520000, version=2]
[EL Fine]: sql: UPDATE EMP2 SET SAL = ?, VERSION = ? WHERE ((EMPNO = ?) AND
(VERSION = ?)) bind => [520000, 3, 101, 2]
T2 flush直後 Emp2 [empno=101, ename=Nishida, sal=520000, version=3]
T2 commit.
T2 commit直後 Emp2 [empno=101, ename=Nishida, sal=520000, version=3]
T2 終了 Emp2 [empno=101, ename=Nishida, sal=520000, version=3]
実行の様子
① T1が検索、WRTIEロックを取得
→sal=500000, version = 1
② T2が検索しようとするが、T1がWRITEロックを取
得しているので、DB内の待ち行列に入る
③ T1がsal=500000+10000, version=1+1で更新
→コミットしたらロック解放
④ T2が待ち行列から出て検索、WRITEロックを取得
→sal=510000, version=2
⑤ T2がsal=510000+10000, version=2+1で更新
→コミットしたらロック解放
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 46
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 47
EclipseLink×PostgreSQL
の場合
EclipseLink×MySQLと挙動は同じ
以下、ログのみ記載
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 48
NONEの実行ログ
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 49
[EL Fine]: sql: SELECT EMPNO, ENAME, SAL, VERSION FROM EMP2 WHERE (EMPNO = ?)
bind => [101]
[EL Fine]: sql: SELECT EMPNO, ENAME, SAL, VERSION FROM EMP2 WHERE (EMPNO = ?)
bind => [101]
T2 検索直後 Emp2 [empno=101, ename=Nishida, sal=500000, version=1]
T1 検索直後 Emp2 [empno=101, ename=Nishida, sal=500000, version=1]
T2 flush直前 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T1 flush直前 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
[EL Fine]: sql: UPDATE EMP2 SET SAL = ? WHERE (EMPNO = ?) bind => [510000, 101]
[EL Fine]: sql: UPDATE EMP2 SET SAL = ? WHERE (EMPNO = ?) bind => [510000, 101]
T2 flush直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T1 flush直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T2 commit.
T2 commit直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T2 終了 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T1 commit.
T1 commit直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T1 終了 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
OPTIMISTICの実行ログ
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 50
[EL Fine]: sql: SELECT EMPNO, ENAME, SAL, VERSION FROM EMP2 WHERE (EMPNO = ?)
bind => [101]
[EL Fine]: sql: SELECT EMPNO, ENAME, SAL, VERSION FROM EMP2 WHERE (EMPNO = ?)
bind => [101]
T1 検索直後 Emp2 [empno=101, ename=Nishida, sal=500000, version=1]
T2 検索直後 Emp2 [empno=101, ename=Nishida, sal=500000, version=1]
T1 flush直前 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T2 flush直前 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
[EL Fine]: sql: UPDATE EMP2 SET SAL = ?, VERSION = ? WHERE ((EMPNO = ?) AND
(VERSION = ?)) bind => [510000, 2, 101, 1]
[EL Fine]: sql: UPDATE EMP2 SET SAL = ?, VERSION = ? WHERE ((EMPNO = ?) AND
(VERSION = ?)) bind => [510000, 2, 101, 1]
T1 flush直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=2]
T1 commit.
T1 commit直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=2]
T1 終了 Emp2 [empno=101, ename=Nishida, sal=510000, version=2]
T2 例外発生:javax.persistence.OptimisticLockException
T2 rollback.
T2 終了 Emp2 [empno=101, ename=Nishida, sal=510000, version=2]
(以下、スタックトレース)
OPTIMISTIC_FORCE_INCREMENTの実行ログ
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 51
[EL Fine]: sql: SELECT EMPNO, ENAME, SAL, VERSION FROM EMP2 WHERE (EMPNO = ?)
bind => [101]
[EL Fine]: sql: SELECT EMPNO, ENAME, SAL, VERSION FROM EMP2 WHERE (EMPNO = ?)
bind => [101]
T1 検索直後 Emp2 [empno=101, ename=Nishida, sal=500000, version=1]
T2 検索直後 Emp2 [empno=101, ename=Nishida, sal=500000, version=1]
T2 flush直前 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T1 flush直前 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
[EL Fine]: sql: UPDATE EMP2 SET SAL = ?, VERSION = ? WHERE ((EMPNO = ?) AND
(VERSION = ?)) bind => [510000, 2, 101, 1]
[EL Fine]: sql: UPDATE EMP2 SET SAL = ?, VERSION = ? WHERE ((EMPNO = ?) AND
(VERSION = ?)) bind => [510000, 2, 101, 1]
T1 flush直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=2]
T1 commit.
T1 commit直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=2]
T1 終了 Emp2 [empno=101, ename=Nishida, sal=510000, version=2]
T2 例外発生:javax.persistence.OptimisticLockException
T2 rollback.
T2 終了 Emp2 [empno=101, ename=Nishida, sal=510000, version=2]
PESSIMISTIC_READの実行ログ
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 52
[EL Fine]: sql: SELECT EMPNO, ENAME, SAL, VERSION FROM EMP2 WHERE (EMPNO = ?)
FOR UPDATE bind => [101]
T2 検索直後 Emp2 [empno=101, ename=Nishida, sal=500000, version=1]
[EL Fine]: sql: SELECT EMPNO, ENAME, SAL, VERSION FROM EMP2 WHERE (EMPNO = ?)
FOR UPDATE bind => [101]
T2 flush直前 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
[EL Fine]: sql: UPDATE EMP2 SET SAL = ? WHERE (EMPNO = ?) bind => [510000, 101]
T2 flush直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T2 commit.
T2 commit直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T2 終了 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T1 検索直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T1 flush直前 Emp2 [empno=101, ename=Nishida, sal=520000, version=1]
[EL Fine]: sql: UPDATE EMP2 SET SAL = ? WHERE (EMPNO = ?) bind => [520000, 101]
T1 flush直後 Emp2 [empno=101, ename=Nishida, sal=520000, version=1]
T1 commit.
T1 commit直後 Emp2 [empno=101, ename=Nishida, sal=520000, version=1]
T1 終了 Emp2 [empno=101, ename=Nishida, sal=520000, version=1]
PESSIMISTIC_WRITEの実行ログ
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 53
[EL Fine]: sql: SELECT EMPNO, ENAME, SAL, VERSION FROM EMP2 WHERE (EMPNO = ?)
FOR UPDATE bind => [101]
T1 検索直後 Emp2 [empno=101, ename=Nishida, sal=500000, version=1]
[EL Fine]: sql: SELECT EMPNO, ENAME, SAL, VERSION FROM EMP2 WHERE (EMPNO = ?)
FOR UPDATE bind => [101]
T1 flush直前 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
[EL Fine]: sql: UPDATE EMP2 SET SAL = ? WHERE (EMPNO = ?) bind => [510000, 101]
T1 flush直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T2 検索直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T1 commit.
T1 commit直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T1 終了 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T2 flush直前 Emp2 [empno=101, ename=Nishida, sal=520000, version=1]
[EL Fine]: sql: UPDATE EMP2 SET SAL = ? WHERE (EMPNO = ?) bind => [520000, 101]
T2 flush直後 Emp2 [empno=101, ename=Nishida, sal=520000, version=1]
T2 commit.
T2 commit直後 Emp2 [empno=101, ename=Nishida, sal=520000, version=1]
T2 終了 Emp2 [empno=101, ename=Nishida, sal=520000, version=1]
PESSIMISTIC_FORCE_INCREMENTの実行ログ
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 54
[EL Fine]: sql: SELECT EMPNO, ENAME, SAL, VERSION FROM EMP2 WHERE (EMPNO = ?)
FOR UPDATE bind => [101]
T2 検索直後 Emp2 [empno=101, ename=Nishida, sal=500000, version=1]
[EL Fine]: sql: SELECT EMPNO, ENAME, SAL, VERSION FROM EMP2 WHERE (EMPNO = ?)
FOR UPDATE bind => [101]
T2 flush直前 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
[EL Fine]: sql: UPDATE EMP2 SET SAL = ?, VERSION = ? WHERE ((EMPNO = ?) AND
(VERSION = ?)) bind => [510000, 2, 101, 1]
T2 flush直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=2]
T1 検索直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=2]
T2 commit.
T2 commit直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=2]
T2 終了 Emp2 [empno=101, ename=Nishida, sal=510000, version=2]
T1 flush直前 Emp2 [empno=101, ename=Nishida, sal=520000, version=2]
[EL Fine]: sql: UPDATE EMP2 SET SAL = ?, VERSION = ? WHERE ((EMPNO = ?) AND
(VERSION = ?)) bind => [520000, 3, 101, 2]
T1 flush直後 Emp2 [empno=101, ename=Nishida, sal=520000, version=3]
T1 commit.
T1 commit直後 Emp2 [empno=101, ename=Nishida, sal=520000, version=3]
T1 終了 Emp2 [empno=101, ename=Nishida, sal=520000, version=3]
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 55
Hibernate×MySQLの場合
NONE
発行されるSQLが微妙に異なるが、最終結果は
EclipseLinkと同じ
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 56
NONEの実行ログ
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 57
Hibernate: select emp2x0_.empno as empno1_0_0_, emp2x0_.ename as ename2_0_0_,
emp2x0_.sal as sal3_0_0_, emp2x0_.version as version4_0_0_ from Emp2 emp2x0_ where
emp2x0_.empno=?
Hibernate: select emp2x0_.empno as empno1_0_0_, emp2x0_.ename as ename2_0_0_,
emp2x0_.sal as sal3_0_0_, emp2x0_.version as version4_0_0_ from Emp2 emp2x0_ where
emp2x0_.empno=?
T1 検索直後 Emp2 [empno=101, ename=Nishida, sal=500000, version=1]
T2 検索直後 Emp2 [empno=101, ename=Nishida, sal=500000, version=1]
T2 flush直前 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T1 flush直前 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
Hibernate: update Emp2 set ename=?, sal=?, version=? where empno=?
Hibernate: update Emp2 set ename=?, sal=?, version=? where empno=?
T2 flush直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T1 flush直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T2 commit.
T2 commit直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T2 終了 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T1 commit.
T1 commit直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T1 終了 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
OPTIMISTIC
ロールバックされたエンティティのバージョンはイ
ンクリメントされない
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 58
OPTIMISTICの実行ログ
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 59
Hibernate: select emp2x0_.empno as empno1_0_0_, emp2x0_.ename as ename2_0_0_,
emp2x0_.sal as sal3_0_0_, emp2x0_.version as version4_0_0_ from Emp2 emp2x0_ where
emp2x0_.empno=?
Hibernate: select emp2x0_.empno as empno1_0_0_, emp2x0_.ename as ename2_0_0_,
emp2x0_.sal as sal3_0_0_, emp2x0_.version as version4_0_0_ from Emp2 emp2x0_ where
emp2x0_.empno=?
T1 検索直後 Emp2 [empno=101, ename=Nishida, sal=500000, version=1]
T2 検索直後 Emp2 [empno=101, ename=Nishida, sal=500000, version=1]
T1 flush直前 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T2 flush直前 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
Hibernate: update Emp2 set ename=?, sal=?, version=? where empno=? and version=?
Hibernate: update Emp2 set ename=?, sal=?, version=? where empno=? and version=?
T1 flush直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=2]
Hibernate: select version from Emp2 where empno =?
T2 例外発生:javax.persistence.OptimisticLockException
T1 commit.
T1 commit直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=2]
T1 終了 Emp2 [empno=101, ename=Nishida, sal=510000, version=2]
T2 rollback.
T2 終了 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
実行後のバージョン値
ロールバックされたエンティティは、バージョン値
がインクリメントされない
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 60
T2 例外発生:javax.persistence.OptimisticLockException
T1 commit.
T1 commit直後 Emp2 [empno=101, ename=Nishida,
sal=510000, version=2]
T1 終了 Emp2 [empno=101, ename=Nishida, sal=510000,
version=2]
T2 rollback.
T2 終了 Emp2 [empno=101, ename=Nishida, sal=510000,
version=1]
謎のSELECT文
T1がcommit時に発行している
→コミット前に、他のトランザクションからバージ
ョンが変更されていないかどうかを確かめるため
と思われる
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 61
T1 flush直後 Emp2 [empno=101, ename=Nishida,
sal=510000, version=2]
Hibernate: select version from Emp2 where empno =?
T2 例外発生:javax.persistence.OptimisticLockException
OPTIMISTIC_FORCE_INCREMENT
flush時とcommit時の2回、バージョンがインクリ
メントされる
「謎のSELECT文」によるバージョン確認は無い
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 62
OPTIMISTIC_FORCE_INCREMENTの実行ログ
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 63
Hibernate: select emp2x0_.empno as empno1_0_0_, emp2x0_.ename as ename2_0_0_,
emp2x0_.sal as sal3_0_0_, emp2x0_.version as version4_0_0_ from Emp2 emp2x0_ where
emp2x0_.empno=?
Hibernate: select emp2x0_.empno as empno1_0_0_, emp2x0_.ename as ename2_0_0_,
emp2x0_.sal as sal3_0_0_, emp2x0_.version as version4_0_0_ from Emp2 emp2x0_ where
emp2x0_.empno=?
T2 検索直後 Emp2 [empno=101, ename=Nishida, sal=500000, version=1]
T1 検索直後 Emp2 [empno=101, ename=Nishida, sal=500000, version=1]
T1 flush直前 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T2 flush直前 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
Hibernate: update Emp2 set ename=?, sal=?, version=? where empno=? and version=?
Hibernate: update Emp2 set ename=?, sal=?, version=? where empno=? and version=?
T2 flush直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=2]
Hibernate: update Emp2 set version=? where empno=? and version=?
T1 例外発生:javax.persistence.OptimisticLockException
T2 commit.
T2 commit直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=3]
T2 終了 Emp2 [empno=101, ename=Nishida, sal=510000, version=3]
T1 rollback.
T1 終了 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
実行後のバージョン値
flush時・commit時の2回、バージョンがインクリメントされ
る
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 64
T2 flush直前 Emp2 [empno=101, ename=Nishida,
sal=510000, version=1]
Hibernate: update Emp2 set ename=?, sal=?, version=?
where empno=? and version=?
T2 flush直後 Emp2 [empno=101, ename=Nishida,
sal=510000, version=2]
Hibernate: update Emp2 set version=? where empno=? and
version=?
T2 commit.
T2 commit直後 Emp2 [empno=101, ename=Nishida,
sal=510000, version=3]
PESSIMISTIC_READ
SELECT・・・LOCK IN SHARE MODE文が実行さ
れ、READロックが取得される
→T1とT2が互いにロック解放待ちとなり、
デッドロック発生
→片方はロールバックされ、
もう片方のみがコミットされる
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 65
PESSIMISTIC_READの実行ログ
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 66
Hibernate: select emp2x0_.empno as empno1_0_0_, emp2x0_.ename as ename2_0_0_,
emp2x0_.sal as sal3_0_0_, emp2x0_.version as version4_0_0_ from Emp2 emp2x0_ where
emp2x0_.empno=? lock in share mode
Hibernate: select emp2x0_.empno as empno1_0_0_, emp2x0_.ename as ename2_0_0_,
emp2x0_.sal as sal3_0_0_, emp2x0_.version as version4_0_0_ from Emp2 emp2x0_ where
emp2x0_.empno=? lock in share mode
T2 検索直後 Emp2 [empno=101, ename=Nishida, sal=500000, version=1]
T1 検索直後 Emp2 [empno=101, ename=Nishida, sal=500000, version=1]
T1 flush直前 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T2 flush直前 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
Hibernate: update Emp2 set ename=?, sal=?, version=? where empno=?
Hibernate: update Emp2 set ename=?, sal=?, version=? where empno=?
T1 flush直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
ERROR: Deadlock found when trying to get lock; try restarting transaction
T1 commit.
T1 commit直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T1 終了 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T2 例外発生:javax.persistence.PersistenceException
T2 rollback.
T2 終了 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
PESSIMISTIC_WRITE
SELECT FOR UPDATE文が実行され、WRITEロ
ックが取得される
→片方のトランザクションがコミット・ロック解放
後、もう片方のトランザクションも実行される
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 67
PESSIMISTIC_WRITEの実行ログ
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 68
Hibernate: select emp2x0_.empno as empno1_0_0_, emp2x0_.ename as ename2_0_0_,
emp2x0_.sal as sal3_0_0_, emp2x0_.version as version4_0_0_ from Emp2 emp2x0_ where
emp2x0_.empno=? for update
Hibernate: select emp2x0_.empno as empno1_0_0_, emp2x0_.ename as ename2_0_0_,
emp2x0_.sal as sal3_0_0_, emp2x0_.version as version4_0_0_ from Emp2 emp2x0_ where
emp2x0_.empno=? for update
T1 検索直後 Emp2 [empno=101, ename=Nishida, sal=500000, version=1]
T1 flush直前 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
Hibernate: update Emp2 set ename=?, sal=?, version=? where empno=?
T1 flush直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T2 検索直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T1 commit.
T1 commit直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T1 終了 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
Hibernate: update Emp2 set ename=?, sal=?, version=? where empno=?
T2 flush直後 Emp2 [empno=101, ename=Nishida, sal=520000, version=1]
T2 commit.
T2 commit直後 Emp2 [empno=101, ename=Nishida, sal=520000, version=1]
T2 終了 Emp2 [empno=101, ename=Nishida, sal=520000, version=1]
PESSIMISTIC_FORCE_INCREMENT
SELECT FOR UPDATE文が実行され、WRITEロ
ックが取得される
→片方のトランザクションがコミット・ロック解放
後、もう片方のトランザクションも実行される
OPTIMISTIC_FORCE_INCREMENTと同様、
flush時・commit時の2回、バージョンがインクリ
メントされる
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 69
PESSIMISTIC_FORCE_INCREMENTの実行ログ
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 70
Hibernate: select emp2x0_.empno as empno1_0_0_, emp2x0_.ename as ename2_0_0_,
emp2x0_.sal as sal3_0_0_, emp2x0_.version as version4_0_0_ from Emp2 emp2x0_ where
emp2x0_.empno=? for update
Hibernate: select emp2x0_.empno as empno1_0_0_, emp2x0_.ename as ename2_0_0_,
emp2x0_.sal as sal3_0_0_, emp2x0_.version as version4_0_0_ from Emp2 emp2x0_ where
emp2x0_.empno=? for update
Hibernate: update Emp2 set version=? where empno=? and version=?
T1 検索直後 Emp2 [empno=101, ename=Nishida, sal=500000, version=2]
T1 flush直前 Emp2 [empno=101, ename=Nishida, sal=510000, version=2]
Hibernate: update Emp2 set ename=?, sal=?, version=? where empno=? and version=?
T1 flush直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=3]
Hibernate: update Emp2 set version=? where empno=? and version=?
T1 commit.
T1 commit直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=3]
T1 終了 Emp2 [empno=101, ename=Nishida, sal=510000, version=3]
T2 検索直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=4]
T2 flush直前 Emp2 [empno=101, ename=Nishida, sal=520000, version=4]
Hibernate: update Emp2 set ename=?, sal=?, version=? where empno=? and version=?
T2 flush直後 Emp2 [empno=101, ename=Nishida, sal=520000, version=5]
T2 commit.
T2 commit直後 Emp2 [empno=101, ename=Nishida, sal=520000, version=5]
T2 終了 Emp2 [empno=101, ename=Nishida, sal=520000, version=5]
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 71
Hibernate×PostgreSQLの場合
Hibernate×PostgreSQL
PESSIMISTIC_FORCE_INCREMENTのみ、
MySQLの場合と挙動が異なる
READロックはSELECT FOR SHARE文
上記以外は同じなので、ログのみ記載
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 72
NONEの実行ログ
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 73
Hibernate: select emp2x0_.empno as empno1_0_0_, emp2x0_.ename as ename2_0_0_,
emp2x0_.sal as sal3_0_0_, emp2x0_.version as version4_0_0_ from Emp2 emp2x0_ where
emp2x0_.empno=?
Hibernate: select emp2x0_.empno as empno1_0_0_, emp2x0_.ename as ename2_0_0_,
emp2x0_.sal as sal3_0_0_, emp2x0_.version as version4_0_0_ from Emp2 emp2x0_ where
emp2x0_.empno=?
T1 検索直後 Emp2 [empno=101, ename=Nishida, sal=500000, version=1]
T2 検索直後 Emp2 [empno=101, ename=Nishida, sal=500000, version=1]
T1 flush直前 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T2 flush直前 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
Hibernate: update Emp2 set ename=?, sal=?, version=? where empno=?
Hibernate: update Emp2 set ename=?, sal=?, version=? where empno=?
T1 flush直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T2 flush直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T1 commit.
T1 commit直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T1 終了 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T2 commit.
T2 commit直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T2 終了 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
OPTIMISTICの実行ログ
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 74
Hibernate: select emp2x0_.empno as empno1_0_0_, emp2x0_.ename as ename2_0_0_,
emp2x0_.sal as sal3_0_0_, emp2x0_.version as version4_0_0_ from Emp2 emp2x0_ where
emp2x0_.empno=?
Hibernate: select emp2x0_.empno as empno1_0_0_, emp2x0_.ename as ename2_0_0_,
emp2x0_.sal as sal3_0_0_, emp2x0_.version as version4_0_0_ from Emp2 emp2x0_ where
emp2x0_.empno=?
T2 検索直後 Emp2 [empno=101, ename=Nishida, sal=500000, version=1]
T1 検索直後 Emp2 [empno=101, ename=Nishida, sal=500000, version=1]
T2 flush直前 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T1 flush直前 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
Hibernate: update Emp2 set ename=?, sal=?, version=? where empno=? and version=?
Hibernate: update Emp2 set ename=?, sal=?, version=? where empno=? and version=?
T1 flush直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=2]
Hibernate: select version from Emp2 where empno =?
T1 commit.
T1 commit直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=2]
T1 終了 Emp2 [empno=101, ename=Nishida, sal=510000, version=2]
T2 例外発生:javax.persistence.OptimisticLockException
T2 rollback.
T2 終了 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
OPTIMISTIC_FORCE_INCREMENTの実行ログ
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 75
Hibernate: select emp2x0_.empno as empno1_0_0_, emp2x0_.ename as ename2_0_0_,
emp2x0_.sal as sal3_0_0_, emp2x0_.version as version4_0_0_ from Emp2 emp2x0_ where
emp2x0_.empno=?
Hibernate: select emp2x0_.empno as empno1_0_0_, emp2x0_.ename as ename2_0_0_,
emp2x0_.sal as sal3_0_0_, emp2x0_.version as version4_0_0_ from Emp2 emp2x0_ where
emp2x0_.empno=?
T1 検索直後 Emp2 [empno=101, ename=Nishida, sal=500000, version=1]
T2 検索直後 Emp2 [empno=101, ename=Nishida, sal=500000, version=1]
T2 flush直前 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T1 flush直前 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
Hibernate: update Emp2 set ename=?, sal=?, version=? where empno=? and version=?
Hibernate: update Emp2 set ename=?, sal=?, version=? where empno=? and version=?
T1 flush直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=2]
Hibernate: update Emp2 set version=? where empno=? and version=?
T1 commit.
T1 commit直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=3]
T1 終了 Emp2 [empno=101, ename=Nishida, sal=510000, version=3]
T2 例外発生:javax.persistence.OptimisticLockException
T2 rollback.
T2 終了 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
PESSIMISTIC_READの実行ログ
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 76
Hibernate: select emp2x0_.empno as empno1_0_0_, emp2x0_.ename as ename2_0_0_,
emp2x0_.sal as sal3_0_0_, emp2x0_.version as version4_0_0_ from Emp2 emp2x0_ where
emp2x0_.empno=? for share
Hibernate: select emp2x0_.empno as empno1_0_0_, emp2x0_.ename as ename2_0_0_,
emp2x0_.sal as sal3_0_0_, emp2x0_.version as version4_0_0_ from Emp2 emp2x0_ where
emp2x0_.empno=? for share
T1 検索直後 Emp2 [empno=101, ename=Nishida, sal=500000, version=1]
T2 検索直後 Emp2 [empno=101, ename=Nishida, sal=500000, version=1]
T1 flush直前 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T2 flush直前 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
Hibernate: update Emp2 set ename=?, sal=?, version=? where empno=?
Hibernate: update Emp2 set ename=?, sal=?, version=? where empno=?
T1 flush直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
ERROR: ERROR: deadlock detected
T2 例外発生:javax.persistence.PersistenceException
T2 rollback.
T2 終了 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T1 commit.
T1 commit直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T1 終了 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
PESSIMISTIC_WRITEの実行ログ
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 77
Hibernate: select emp2x0_.empno as empno1_0_0_, emp2x0_.ename as ename2_0_0_,
emp2x0_.sal as sal3_0_0_, emp2x0_.version as version4_0_0_ from Emp2 emp2x0_ where
emp2x0_.empno=? for update
Hibernate: select emp2x0_.empno as empno1_0_0_, emp2x0_.ename as ename2_0_0_,
emp2x0_.sal as sal3_0_0_, emp2x0_.version as version4_0_0_ from Emp2 emp2x0_ where
emp2x0_.empno=? for update
T1 検索直後 Emp2 [empno=101, ename=Nishida, sal=500000, version=1]
T1 flush直前 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
Hibernate: update Emp2 set ename=?, sal=?, version=? where empno=?
T1 flush直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T2 検索直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T1 commit.
T1 commit直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T1 終了 Emp2 [empno=101, ename=Nishida, sal=510000, version=1]
T2 flush直前 Emp2 [empno=101, ename=Nishida, sal=520000, version=1]
Hibernate: update Emp2 set ename=?, sal=?, version=? where empno=?
T2 flush直後 Emp2 [empno=101, ename=Nishida, sal=520000, version=1]
T2 commit.
T2 commit直後 Emp2 [empno=101, ename=Nishida, sal=520000, version=1]
T2 終了 Emp2 [empno=101, ename=Nishida, sal=520000, version=1]
PESSIMISTIC_FORCE_INCREMENT
SELECT FOR UPDATE文にNOWAITオプション
が付加される
→後からのトランザクションは、待つことができな
いため例外発生
NOWAITオプションはMySQLには無い
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 78
PESSIMISTIC_FORCE_INCREMENTの実行ログ
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 79
Hibernate: select emp2x0_.empno as empno1_0_0_, emp2x0_.ename as ename2_0_0_,
emp2x0_.sal as sal3_0_0_, emp2x0_.version as version4_0_0_ from Emp2 emp2x0_ where
emp2x0_.empno=? for update nowait
ERROR: ERROR: could not obtain lock on row in relation "emp2"
Hibernate: select emp2x0_.empno as empno1_0_0_, emp2x0_.ename as ename2_0_0_,
emp2x0_.sal as sal3_0_0_, emp2x0_.version as version4_0_0_ from Emp2 emp2x0_ where
emp2x0_.empno=? for update nowait
Hibernate: update Emp2 set version=? where empno=? and version=?
T1 検索直後 Emp2 [empno=101, ename=Nishida, sal=500000, version=2]
T1 flush直前 Emp2 [empno=101, ename=Nishida, sal=510000, version=2]
Hibernate: update Emp2 set ename=?, sal=?, version=? where empno=? and version=?
T1 flush直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=3]
T1 commit.
T1 commit直後 Emp2 [empno=101, ename=Nishida, sal=510000, version=3]
T1 終了 Emp2 [empno=101, ename=Nishida, sal=510000, version=3]
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 80
まとめ
まとめ
ロックモード 相違点
OPTIMISTIC ・EclipseLinkでは、ロールバックされたエン
ティティのバージョン値もインクリメントされる
OPTIMISTIC_FORC
E_INCREMENT
・Hibernateでは、flush時とcommit時の2回、
バージョンがインクリメントされる
PESSIMISTIC_REA
D
・EclipseLinkでは、READロックではなく
WRITEロックになる
PESSIMISTIC_FOR
CE_INCREMENT
・Hibernateでは、flush時とcommit時の2回、
バージョンがインクリメントされる
・Hibernate×PostgreSQLでは、SELECT
FOR UPDATE文にNOWAITオプションが付加
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 81
開発時の注意
必ずSQLログを出力して、一通りの挙動を確認し
ておきましょう!
JPAのSQLログの順番は、実際にDB内で実行さ
れる順番とは異なる場合があるので、注意しま
しょう!
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 82
今回、入れられなかった内容
悲観的ロックのタイムアウト
javax.persistence.lock.timeout
悲観的ロックのスコープ
javax.persistence.lock.scope
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 83
技術の普及=教育の普及
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 84
教育の
普及
技術の
普及
Copyright UCHIDA HUMAN DEVELOPMENT all rights reserved. 85

More Related Content

What's hot

Z OS IBM Utilities
Z OS IBM UtilitiesZ OS IBM Utilities
Z OS IBM Utilitieskapa rohit
 
MySQLerの7つ道具 plus
MySQLerの7つ道具 plusMySQLerの7つ道具 plus
MySQLerの7つ道具 plusyoku0825
 
雑なMySQLパフォーマンスチューニング
雑なMySQLパフォーマンスチューニング雑なMySQLパフォーマンスチューニング
雑なMySQLパフォーマンスチューニングyoku0825
 
はまる!JPA(初学者向けライト版)
はまる!JPA(初学者向けライト版)はまる!JPA(初学者向けライト版)
はまる!JPA(初学者向けライト版)Masatoshi Tada
 
やってはいけない空振りDelete
やってはいけない空振りDeleteやってはいけない空振りDelete
やってはいけない空振りDeleteYu Yamada
 
MySQL 5.7 トラブルシューティング 性能解析入門編
MySQL 5.7 トラブルシューティング 性能解析入門編MySQL 5.7 トラブルシューティング 性能解析入門編
MySQL 5.7 トラブルシューティング 性能解析入門編Mikiya Okuno
 
さいきんの InnoDB Adaptive Flushing (仮)
さいきんの InnoDB Adaptive Flushing (仮)さいきんの InnoDB Adaptive Flushing (仮)
さいきんの InnoDB Adaptive Flushing (仮)Takanori Sejima
 
Java ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsugJava ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsugMasatoshi Tada
 
BHyVeってなんや
BHyVeってなんやBHyVeってなんや
BHyVeってなんやTakuya ASADA
 
Oracle db performance tuning
Oracle db performance tuningOracle db performance tuning
Oracle db performance tuningSimon Huang
 
V$SQLとその周辺でER図を描いてみよう!
V$SQLとその周辺でER図を描いてみよう!V$SQLとその周辺でER図を描いてみよう!
V$SQLとその周辺でER図を描いてみよう!歩 柴田
 
「金融API向けOAuth」にみるOAuthプロファイリングの実際 #secjaws #finsecjaws01 #oauth #oidc #api
「金融API向けOAuth」にみるOAuthプロファイリングの実際 #secjaws #finsecjaws01 #oauth #oidc #api「金融API向けOAuth」にみるOAuthプロファイリングの実際 #secjaws #finsecjaws01 #oauth #oidc #api
「金融API向けOAuth」にみるOAuthプロファイリングの実際 #secjaws #finsecjaws01 #oauth #oidc #apiTatsuo Kudo
 
MySQL 5.7が魅せる新しい運用の形
MySQL 5.7が魅せる新しい運用の形MySQL 5.7が魅せる新しい運用の形
MySQL 5.7が魅せる新しい運用の形yoku0825
 
SQL Server パフォーマンス問題対処 Deep Dive
SQL Server パフォーマンス問題対処 Deep DiveSQL Server パフォーマンス問題対処 Deep Dive
SQL Server パフォーマンス問題対処 Deep DiveKoichiro Sasaki
 

What's hot (20)

Z OS IBM Utilities
Z OS IBM UtilitiesZ OS IBM Utilities
Z OS IBM Utilities
 
MySQLerの7つ道具 plus
MySQLerの7つ道具 plusMySQLerの7つ道具 plus
MySQLerの7つ道具 plus
 
雑なMySQLパフォーマンスチューニング
雑なMySQLパフォーマンスチューニング雑なMySQLパフォーマンスチューニング
雑なMySQLパフォーマンスチューニング
 
分散トレーシング技術について(Open tracingやjaeger)
分散トレーシング技術について(Open tracingやjaeger)分散トレーシング技術について(Open tracingやjaeger)
分散トレーシング技術について(Open tracingやjaeger)
 
はまる!JPA(初学者向けライト版)
はまる!JPA(初学者向けライト版)はまる!JPA(初学者向けライト版)
はまる!JPA(初学者向けライト版)
 
やってはいけない空振りDelete
やってはいけない空振りDeleteやってはいけない空振りDelete
やってはいけない空振りDelete
 
MySQL 5.7 トラブルシューティング 性能解析入門編
MySQL 5.7 トラブルシューティング 性能解析入門編MySQL 5.7 トラブルシューティング 性能解析入門編
MySQL 5.7 トラブルシューティング 性能解析入門編
 
RESTfulとは
RESTfulとはRESTfulとは
RESTfulとは
 
さいきんの InnoDB Adaptive Flushing (仮)
さいきんの InnoDB Adaptive Flushing (仮)さいきんの InnoDB Adaptive Flushing (仮)
さいきんの InnoDB Adaptive Flushing (仮)
 
AWR and ASH Deep Dive
AWR and ASH Deep DiveAWR and ASH Deep Dive
AWR and ASH Deep Dive
 
Java ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsugJava ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsug
 
Oracle Data Guard による高可用性
Oracle Data Guard による高可用性Oracle Data Guard による高可用性
Oracle Data Guard による高可用性
 
BHyVeってなんや
BHyVeってなんやBHyVeってなんや
BHyVeってなんや
 
Oracle db performance tuning
Oracle db performance tuningOracle db performance tuning
Oracle db performance tuning
 
V$SQLとその周辺でER図を描いてみよう!
V$SQLとその周辺でER図を描いてみよう!V$SQLとその周辺でER図を描いてみよう!
V$SQLとその周辺でER図を描いてみよう!
 
「金融API向けOAuth」にみるOAuthプロファイリングの実際 #secjaws #finsecjaws01 #oauth #oidc #api
「金融API向けOAuth」にみるOAuthプロファイリングの実際 #secjaws #finsecjaws01 #oauth #oidc #api「金融API向けOAuth」にみるOAuthプロファイリングの実際 #secjaws #finsecjaws01 #oauth #oidc #api
「金融API向けOAuth」にみるOAuthプロファイリングの実際 #secjaws #finsecjaws01 #oauth #oidc #api
 
MySQL 5.7が魅せる新しい運用の形
MySQL 5.7が魅せる新しい運用の形MySQL 5.7が魅せる新しい運用の形
MySQL 5.7が魅せる新しい運用の形
 
オラクルのHadoopソリューションご紹介
オラクルのHadoopソリューションご紹介オラクルのHadoopソリューションご紹介
オラクルのHadoopソリューションご紹介
 
SQL Server パフォーマンス問題対処 Deep Dive
SQL Server パフォーマンス問題対処 Deep DiveSQL Server パフォーマンス問題対処 Deep Dive
SQL Server パフォーマンス問題対処 Deep Dive
 
Oracle GoldenGate アーキテクチャと基本機能
Oracle GoldenGate アーキテクチャと基本機能Oracle GoldenGate アーキテクチャと基本機能
Oracle GoldenGate アーキテクチャと基本機能
 

Viewers also liked

Java EE 8先取り!MVC 1.0入門 [EDR2対応版] 2015-10-10更新
Java EE 8先取り!MVC 1.0入門 [EDR2対応版] 2015-10-10更新Java EE 8先取り!MVC 1.0入門 [EDR2対応版] 2015-10-10更新
Java EE 8先取り!MVC 1.0入門 [EDR2対応版] 2015-10-10更新Masatoshi Tada
 
NetBeansでかんたんJava EE ○分間クッキング! #kuwaccho lt
NetBeansでかんたんJava EE ○分間クッキング! #kuwaccho ltNetBeansでかんたんJava EE ○分間クッキング! #kuwaccho lt
NetBeansでかんたんJava EE ○分間クッキング! #kuwaccho ltMasatoshi Tada
 
ステップ・バイ・ステップで学ぶラムダ式・Stream api入門 #jjug ccc #ccc h2
ステップ・バイ・ステップで学ぶラムダ式・Stream api入門 #jjug ccc #ccc h2ステップ・バイ・ステップで学ぶラムダ式・Stream api入門 #jjug ccc #ccc h2
ステップ・バイ・ステップで学ぶラムダ式・Stream api入門 #jjug ccc #ccc h2Masatoshi Tada
 
Getting start Java EE Action-Based MVC with Thymeleaf
Getting start Java EE Action-Based MVC with ThymeleafGetting start Java EE Action-Based MVC with Thymeleaf
Getting start Java EE Action-Based MVC with ThymeleafMasatoshi Tada
 
Java EEハンズオン資料 JJUG CCC 2015 Fall
Java EEハンズオン資料 JJUG CCC 2015 FallJava EEハンズオン資料 JJUG CCC 2015 Fall
Java EEハンズオン資料 JJUG CCC 2015 FallMasatoshi Tada
 
Dockerで始める Java EE アプリケーション開発 for JJUG CCC 2017
Dockerで始める Java EE アプリケーション開発 for JJUG CCC 2017Dockerで始める Java EE アプリケーション開発 for JJUG CCC 2017
Dockerで始める Java EE アプリケーション開発 for JJUG CCC 2017Kohei Saito
 
Java SE 9の紹介: モジュール・システムを中心に
Java SE 9の紹介: モジュール・システムを中心にJava SE 9の紹介: モジュール・システムを中心に
Java SE 9の紹介: モジュール・システムを中心にTaku Miyakawa
 
Spring Bootの本当の理解ポイント #jjug
Spring Bootの本当の理解ポイント #jjugSpring Bootの本当の理解ポイント #jjug
Spring Bootの本当の理解ポイント #jjugMasatoshi Tada
 

Viewers also liked (8)

Java EE 8先取り!MVC 1.0入門 [EDR2対応版] 2015-10-10更新
Java EE 8先取り!MVC 1.0入門 [EDR2対応版] 2015-10-10更新Java EE 8先取り!MVC 1.0入門 [EDR2対応版] 2015-10-10更新
Java EE 8先取り!MVC 1.0入門 [EDR2対応版] 2015-10-10更新
 
NetBeansでかんたんJava EE ○分間クッキング! #kuwaccho lt
NetBeansでかんたんJava EE ○分間クッキング! #kuwaccho ltNetBeansでかんたんJava EE ○分間クッキング! #kuwaccho lt
NetBeansでかんたんJava EE ○分間クッキング! #kuwaccho lt
 
ステップ・バイ・ステップで学ぶラムダ式・Stream api入門 #jjug ccc #ccc h2
ステップ・バイ・ステップで学ぶラムダ式・Stream api入門 #jjug ccc #ccc h2ステップ・バイ・ステップで学ぶラムダ式・Stream api入門 #jjug ccc #ccc h2
ステップ・バイ・ステップで学ぶラムダ式・Stream api入門 #jjug ccc #ccc h2
 
Getting start Java EE Action-Based MVC with Thymeleaf
Getting start Java EE Action-Based MVC with ThymeleafGetting start Java EE Action-Based MVC with Thymeleaf
Getting start Java EE Action-Based MVC with Thymeleaf
 
Java EEハンズオン資料 JJUG CCC 2015 Fall
Java EEハンズオン資料 JJUG CCC 2015 FallJava EEハンズオン資料 JJUG CCC 2015 Fall
Java EEハンズオン資料 JJUG CCC 2015 Fall
 
Dockerで始める Java EE アプリケーション開発 for JJUG CCC 2017
Dockerで始める Java EE アプリケーション開発 for JJUG CCC 2017Dockerで始める Java EE アプリケーション開発 for JJUG CCC 2017
Dockerで始める Java EE アプリケーション開発 for JJUG CCC 2017
 
Java SE 9の紹介: モジュール・システムを中心に
Java SE 9の紹介: モジュール・システムを中心にJava SE 9の紹介: モジュール・システムを中心に
Java SE 9の紹介: モジュール・システムを中心に
 
Spring Bootの本当の理解ポイント #jjug
Spring Bootの本当の理解ポイント #jjugSpring Bootの本当の理解ポイント #jjug
Spring Bootの本当の理解ポイント #jjug
 

Similar to JPAの同時実行制御とロック20140518 #ccc_r15 #jjug_ccc

2015年度GPGPU実践基礎工学 第15回 GPGPU開発環境 (OpenCL)
2015年度GPGPU実践基礎工学 第15回 GPGPU開発環境(OpenCL)2015年度GPGPU実践基礎工学 第15回 GPGPU開発環境(OpenCL)
2015年度GPGPU実践基礎工学 第15回 GPGPU開発環境 (OpenCL)智啓 出川
 
20121217 jawsug-yokohama
20121217 jawsug-yokohama20121217 jawsug-yokohama
20121217 jawsug-yokohamaTetsuya Chiba
 
Zマイスターとの新たな価値探求 z/OS
Zマイスターとの新たな価値探求 z/OSZマイスターとの新たな価値探求 z/OS
Zマイスターとの新たな価値探求 z/OSIBMソリューション
 
20180613 [TensorFlow分散学習] Horovodによる分散学習の実装方法と解説
20180613 [TensorFlow分散学習] Horovodによる分散学習の実装方法と解説20180613 [TensorFlow分散学習] Horovodによる分散学習の実装方法と解説
20180613 [TensorFlow分散学習] Horovodによる分散学習の実装方法と解説LeapMind Inc
 
Cell/B.E. プログラミング事始め
Cell/B.E. プログラミング事始めCell/B.E. プログラミング事始め
Cell/B.E. プログラミング事始めYou&I
 
リアルタイムOsのカスタマイズ
リアルタイムOsのカスタマイズリアルタイムOsのカスタマイズ
リアルタイムOsのカスタマイズKazuhiro Takahashi
 
LAMMPS クラウド活用勉強会説明資料(Rescale編) 2017/01/24
LAMMPS クラウド活用勉強会説明資料(Rescale編) 2017/01/24LAMMPS クラウド活用勉強会説明資料(Rescale編) 2017/01/24
LAMMPS クラウド活用勉強会説明資料(Rescale編) 2017/01/24Rescale Japan株式会社
 
JDK 13 New Features [MeetUp with Java Experts! @Gaienmae/Dojima 2019]
JDK 13 New Features [MeetUp with Java Experts! @Gaienmae/Dojima 2019]JDK 13 New Features [MeetUp with Java Experts! @Gaienmae/Dojima 2019]
JDK 13 New Features [MeetUp with Java Experts! @Gaienmae/Dojima 2019]David Buck
 
ReactでuseEffect()を減らしたい話
ReactでuseEffect()を減らしたい話ReactでuseEffect()を減らしたい話
ReactでuseEffect()を減らしたい話iPride Co., Ltd.
 
My sql casual_in_fukuoka_vol1
My sql casual_in_fukuoka_vol1My sql casual_in_fukuoka_vol1
My sql casual_in_fukuoka_vol1Makoto Haruyama
 
IaaSクラウドを支える基礎技術 演習編_v1_0
IaaSクラウドを支える基礎技術 演習編_v1_0IaaSクラウドを支える基礎技術 演習編_v1_0
IaaSクラウドを支える基礎技術 演習編_v1_0Etsuji Nakai
 
Stack Buffer OverFlow
Stack Buffer OverFlowStack Buffer OverFlow
Stack Buffer OverFlowsounakano
 
運用構築技術者の為のPSプログラミング第1回
運用構築技術者の為のPSプログラミング第1回運用構築技術者の為のPSプログラミング第1回
運用構築技術者の為のPSプログラミング第1回Shigeharu Yamaoka
 
MySQL 5.6新機能解説@dbtechshowcase2012
MySQL 5.6新機能解説@dbtechshowcase2012MySQL 5.6新機能解説@dbtechshowcase2012
MySQL 5.6新機能解説@dbtechshowcase2012Mikiya Okuno
 
OpenStack on OpenStack with CI
OpenStack on OpenStack with CIOpenStack on OpenStack with CI
OpenStack on OpenStack with CIkanabuchi
 

Similar to JPAの同時実行制御とロック20140518 #ccc_r15 #jjug_ccc (20)

2015年度GPGPU実践基礎工学 第15回 GPGPU開発環境 (OpenCL)
2015年度GPGPU実践基礎工学 第15回 GPGPU開発環境(OpenCL)2015年度GPGPU実践基礎工学 第15回 GPGPU開発環境(OpenCL)
2015年度GPGPU実践基礎工学 第15回 GPGPU開発環境 (OpenCL)
 
20121217 jawsug-yokohama
20121217 jawsug-yokohama20121217 jawsug-yokohama
20121217 jawsug-yokohama
 
Zマイスターとの新たな価値探求 z/OS
Zマイスターとの新たな価値探求 z/OSZマイスターとの新たな価値探求 z/OS
Zマイスターとの新たな価値探求 z/OS
 
20180613 [TensorFlow分散学習] Horovodによる分散学習の実装方法と解説
20180613 [TensorFlow分散学習] Horovodによる分散学習の実装方法と解説20180613 [TensorFlow分散学習] Horovodによる分散学習の実装方法と解説
20180613 [TensorFlow分散学習] Horovodによる分散学習の実装方法と解説
 
hscj2019_ishizaki_public
hscj2019_ishizaki_publichscj2019_ishizaki_public
hscj2019_ishizaki_public
 
LTspice超入門 マルツエレック marutsuelec
LTspice超入門 マルツエレック marutsuelecLTspice超入門 マルツエレック marutsuelec
LTspice超入門 マルツエレック marutsuelec
 
Cell/B.E. プログラミング事始め
Cell/B.E. プログラミング事始めCell/B.E. プログラミング事始め
Cell/B.E. プログラミング事始め
 
リアルタイムOsのカスタマイズ
リアルタイムOsのカスタマイズリアルタイムOsのカスタマイズ
リアルタイムOsのカスタマイズ
 
about DakotagUI
about DakotagUIabout DakotagUI
about DakotagUI
 
LAMMPS クラウド活用勉強会説明資料(Rescale編) 2017/01/24
LAMMPS クラウド活用勉強会説明資料(Rescale編) 2017/01/24LAMMPS クラウド活用勉強会説明資料(Rescale編) 2017/01/24
LAMMPS クラウド活用勉強会説明資料(Rescale編) 2017/01/24
 
JDK 13 New Features [MeetUp with Java Experts! @Gaienmae/Dojima 2019]
JDK 13 New Features [MeetUp with Java Experts! @Gaienmae/Dojima 2019]JDK 13 New Features [MeetUp with Java Experts! @Gaienmae/Dojima 2019]
JDK 13 New Features [MeetUp with Java Experts! @Gaienmae/Dojima 2019]
 
ReactでuseEffect()を減らしたい話
ReactでuseEffect()を減らしたい話ReactでuseEffect()を減らしたい話
ReactでuseEffect()を減らしたい話
 
My sql casual_in_fukuoka_vol1
My sql casual_in_fukuoka_vol1My sql casual_in_fukuoka_vol1
My sql casual_in_fukuoka_vol1
 
Altanative macro
Altanative macroAltanative macro
Altanative macro
 
IaaSクラウドを支える基礎技術 演習編_v1_0
IaaSクラウドを支える基礎技術 演習編_v1_0IaaSクラウドを支える基礎技術 演習編_v1_0
IaaSクラウドを支える基礎技術 演習編_v1_0
 
MoteMote Compiler Plugin
MoteMote Compiler PluginMoteMote Compiler Plugin
MoteMote Compiler Plugin
 
Stack Buffer OverFlow
Stack Buffer OverFlowStack Buffer OverFlow
Stack Buffer OverFlow
 
運用構築技術者の為のPSプログラミング第1回
運用構築技術者の為のPSプログラミング第1回運用構築技術者の為のPSプログラミング第1回
運用構築技術者の為のPSプログラミング第1回
 
MySQL 5.6新機能解説@dbtechshowcase2012
MySQL 5.6新機能解説@dbtechshowcase2012MySQL 5.6新機能解説@dbtechshowcase2012
MySQL 5.6新機能解説@dbtechshowcase2012
 
OpenStack on OpenStack with CI
OpenStack on OpenStack with CIOpenStack on OpenStack with CI
OpenStack on OpenStack with CI
 

More from Masatoshi Tada

これで怖くない!?コードリーディングで学ぶSpring Security #中央線Meetup
これで怖くない!?コードリーディングで学ぶSpring Security #中央線Meetupこれで怖くない!?コードリーディングで学ぶSpring Security #中央線Meetup
これで怖くない!?コードリーディングで学ぶSpring Security #中央線MeetupMasatoshi Tada
 
Pivotal認定講師によるSpring Framework 5.1 & Spring Boot 2.1ハンズオン! #jjug_ccc
Pivotal認定講師によるSpring Framework 5.1 & Spring Boot 2.1ハンズオン! #jjug_cccPivotal認定講師によるSpring Framework 5.1 & Spring Boot 2.1ハンズオン! #jjug_ccc
Pivotal認定講師によるSpring Framework 5.1 & Spring Boot 2.1ハンズオン! #jjug_cccMasatoshi Tada
 
基礎からのOAuth 2.0とSpring Security 5.1による実装
基礎からのOAuth 2.0とSpring Security 5.1による実装基礎からのOAuth 2.0とSpring Security 5.1による実装
基礎からのOAuth 2.0とSpring Security 5.1による実装Masatoshi Tada
 
初めてでも30分で分かるSpring 5 & Spring Boot 2オーバービュー
初めてでも30分で分かるSpring 5 & Spring Boot 2オーバービュー初めてでも30分で分かるSpring 5 & Spring Boot 2オーバービュー
初めてでも30分で分かるSpring 5 & Spring Boot 2オーバービューMasatoshi Tada
 
ReactiveだけじゃないSpring 5 & Spring Boot 2新機能解説
ReactiveだけじゃないSpring 5 & Spring Boot 2新機能解説ReactiveだけじゃないSpring 5 & Spring Boot 2新機能解説
ReactiveだけじゃないSpring 5 & Spring Boot 2新機能解説Masatoshi Tada
 
Java EE 8新機能解説 -Bean Validation 2.0編-
Java EE 8新機能解説 -Bean Validation 2.0編-Java EE 8新機能解説 -Bean Validation 2.0編-
Java EE 8新機能解説 -Bean Validation 2.0編-Masatoshi Tada
 
JSUG SpringOne 2017報告会
JSUG SpringOne 2017報告会JSUG SpringOne 2017報告会
JSUG SpringOne 2017報告会Masatoshi Tada
 
とにかく分かりづらいTwelve-Factor Appの解説を試みる
とにかく分かりづらいTwelve-Factor Appの解説を試みるとにかく分かりづらいTwelve-Factor Appの解説を試みる
とにかく分かりづらいTwelve-Factor Appの解説を試みるMasatoshi Tada
 
Java EEでもOAuth 2.0!~そしてPayara Micro on Cloud Foundryで遊ぶ~
Java EEでもOAuth 2.0!~そしてPayara Micro on Cloud Foundryで遊ぶ~Java EEでもOAuth 2.0!~そしてPayara Micro on Cloud Foundryで遊ぶ~
Java EEでもOAuth 2.0!~そしてPayara Micro on Cloud Foundryで遊ぶ~Masatoshi Tada
 
Spring Data JPAによるデータアクセス徹底入門 #jsug
Spring Data JPAによるデータアクセス徹底入門 #jsugSpring Data JPAによるデータアクセス徹底入門 #jsug
Spring Data JPAによるデータアクセス徹底入門 #jsugMasatoshi Tada
 

More from Masatoshi Tada (10)

これで怖くない!?コードリーディングで学ぶSpring Security #中央線Meetup
これで怖くない!?コードリーディングで学ぶSpring Security #中央線Meetupこれで怖くない!?コードリーディングで学ぶSpring Security #中央線Meetup
これで怖くない!?コードリーディングで学ぶSpring Security #中央線Meetup
 
Pivotal認定講師によるSpring Framework 5.1 & Spring Boot 2.1ハンズオン! #jjug_ccc
Pivotal認定講師によるSpring Framework 5.1 & Spring Boot 2.1ハンズオン! #jjug_cccPivotal認定講師によるSpring Framework 5.1 & Spring Boot 2.1ハンズオン! #jjug_ccc
Pivotal認定講師によるSpring Framework 5.1 & Spring Boot 2.1ハンズオン! #jjug_ccc
 
基礎からのOAuth 2.0とSpring Security 5.1による実装
基礎からのOAuth 2.0とSpring Security 5.1による実装基礎からのOAuth 2.0とSpring Security 5.1による実装
基礎からのOAuth 2.0とSpring Security 5.1による実装
 
初めてでも30分で分かるSpring 5 & Spring Boot 2オーバービュー
初めてでも30分で分かるSpring 5 & Spring Boot 2オーバービュー初めてでも30分で分かるSpring 5 & Spring Boot 2オーバービュー
初めてでも30分で分かるSpring 5 & Spring Boot 2オーバービュー
 
ReactiveだけじゃないSpring 5 & Spring Boot 2新機能解説
ReactiveだけじゃないSpring 5 & Spring Boot 2新機能解説ReactiveだけじゃないSpring 5 & Spring Boot 2新機能解説
ReactiveだけじゃないSpring 5 & Spring Boot 2新機能解説
 
Java EE 8新機能解説 -Bean Validation 2.0編-
Java EE 8新機能解説 -Bean Validation 2.0編-Java EE 8新機能解説 -Bean Validation 2.0編-
Java EE 8新機能解説 -Bean Validation 2.0編-
 
JSUG SpringOne 2017報告会
JSUG SpringOne 2017報告会JSUG SpringOne 2017報告会
JSUG SpringOne 2017報告会
 
とにかく分かりづらいTwelve-Factor Appの解説を試みる
とにかく分かりづらいTwelve-Factor Appの解説を試みるとにかく分かりづらいTwelve-Factor Appの解説を試みる
とにかく分かりづらいTwelve-Factor Appの解説を試みる
 
Java EEでもOAuth 2.0!~そしてPayara Micro on Cloud Foundryで遊ぶ~
Java EEでもOAuth 2.0!~そしてPayara Micro on Cloud Foundryで遊ぶ~Java EEでもOAuth 2.0!~そしてPayara Micro on Cloud Foundryで遊ぶ~
Java EEでもOAuth 2.0!~そしてPayara Micro on Cloud Foundryで遊ぶ~
 
Spring Data JPAによるデータアクセス徹底入門 #jsug
Spring Data JPAによるデータアクセス徹底入門 #jsugSpring Data JPAによるデータアクセス徹底入門 #jsug
Spring Data JPAによるデータアクセス徹底入門 #jsug
 

JPAの同時実行制御とロック20140518 #ccc_r15 #jjug_ccc