色んなところで既に書かれてるので、今日のは完全に自分向けのメモ(^^;
JPAの楽観ロック、知識としては知っていたのですが試したことなくて、ちょうどやる必要が出たので、まずは簡単なサンプルで確認してみました。
プログラムは営業系のシステムをイメージして、商談データがあって、2人の人が同じデータを取得して変更して更新してしまった、という流れです。
環境
環境はWindows 7上のNetBeans 7.3でJava EE 6 & JDK7、GlassFish3.1.2でEclipseLink2.3.2です。データベースはMicrosoft SQL Server 2008 R2。
テーブルは超簡易で以下のようなものです。
商談ID |
商談名 |
Version |
作成日 |
更新日 |
0 |
商談1だよ |
0 |
2013-10-10 19:51:55.793 |
2013-10-10 19:51:56.060 |
Versionカラムは楽観ロック用に設けたものです。
動作
まず結果から。
サンプルアプリをデプロイして、ブラウザを2つ起動してアクセスします。


1つ目のテキストにDBにある商談ID「0」を指定して「読込」ボタンを押します。
DBから読み込んで商談名が表示されます。


IEのブラウザは「商談2なんです」と名称を書き換えます。
もう1つのFirefoxでは「商談3なんだよ!」と名称を書き換えます。


で、各々で「保存」ボタンを押下!
NetBeansではブレイクポイントで複数のスレッドが止まると以下のような歯車マークになります。

NetBeansのマルチスレッドデバッグは過去に書いてました。
NetBeansでマルチスレッドデバッグ
oppFacade.edit(myOpp)という所でEJB側でDB保存処理されます。
成功したのでDBを確認します。

保存されてますね。そしてVersionカラムの値が「1」とカウントアップされてます(^^)
ここに関しては後程。
ではもう1つのFirefoxから来たほうのスレッドに切り替えて

保存処理を実行してみます。

するとエラーに!
GlassFishをみると

OptimisticLockExceptionとなっています(^^)取得した時点でVersionが0で、書き込もうとしたらVersionが既に1となっていたため、「誰かが書き込んだやろ」と判定した流れかと。
EJB使うとBean側ではjavax.ejb.EJBExceptionに成り代わってしまうのが悲しいですが、EJB側でちゃんとcatchすればいける…のかな多分(^^;未確認