openjpa-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From allee8...@apache.org
Subject svn commit: r747489 [4/5] - in /openjpa/trunk: openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/ openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/sql/ openjpa-kernel/src/main/java/...
Date Tue, 24 Feb 2009 18:48:11 GMT
Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/lockmgr/TestPessimisticLockManager.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/lockmgr/TestPessimisticLockManager.java?rev=747489&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/lockmgr/TestPessimisticLockManager.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/lockmgr/TestPessimisticLockManager.java Tue Feb 24 18:48:09 2009
@@ -0,0 +1,1566 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.lockmgr;
+
+import javax.persistence.LockModeType;
+
+import org.apache.openjpa.persistence.test.AllowFailure;
+
+/**
+ * Test JPA 2.0 LockTypeMode semantics using OpenJPA pessimistic
+ * "pessimistic" lock manager.
+ *
+ * @author Albert Lee
+ * @since 2.0.0
+ */
+public class TestPessimisticLockManager extends LockManagerTestBase {
+    
+    public void setUp() {
+        setUp(LockEmployee.class, LockTask.class, LockStory.class
+            , "openjpa.LockManager", "pessimistic"
+//          , "openjpa.jdbc.FinderCache", "false"
+        );
+        commonSetUp();        
+    }
+    
+    public void testFindLockRead() {
+        getLog().info("---> testFindLockRead()");
+        commonTestSequence(
+            LockModeType.READ,
+            2,
+            0,
+            commonSelectForUpdate,
+            null,
+            commonSelectForUpdate,
+            null        
+        );
+    }
+    
+    public void testFindLockWrite() {
+        getLog().info("---> testFindLockWrite()");
+        commonTestSequence(
+            LockModeType.WRITE,
+            1,
+            0,
+            commonSelectForUpdate,
+            null,
+            commonSelectForUpdate,
+            null
+        );
+    }
+    
+    public void testFindLockOptimistic() {
+        getLog().info("---> testFindLockOptimistic()");
+        commonTestSequence(
+            LockModeType.OPTIMISTIC,
+            2,
+            0,
+            commonSelectForUpdate,
+            null,
+            commonSelectForUpdate,
+            null        
+        );
+    }
+    
+    public void testFindLockOptimisticForceIncrement() {
+        getLog().info("---> testFindLockOptimisticForceIncrement()");
+        commonTestSequence(
+            LockModeType.OPTIMISTIC_FORCE_INCREMENT,
+            1,
+            0,
+            commonSelectForUpdate,
+            null,
+            commonSelectForUpdate,
+            null
+        );
+    }
+    
+    public void testFindLockPessimisticRead() {
+        getLog().info("---> testFindLockPessimisticRead()");
+        commonTestSequence(
+// TODO:            LockModeType.PESSIMISTIC_SHARED,   
+            LockModeType.PESSIMISTIC,   
+            2,
+            0,
+            commonSelectForUpdate,
+            null,
+            commonSelectForUpdate,
+            null
+        );
+    }
+    
+    public void testFindLockPessimisticWrite() {
+        getLog().info("---> testFindLockPessimisticWrite()");
+        commonTestSequence(
+// TODO:            LockModeType.PESSIMISTIC_WRITE,   
+            LockModeType.PESSIMISTIC,   
+            1,
+            0,
+            commonSelectForUpdate,
+            null,
+            commonSelectForUpdate,
+            null
+        );
+    }
+    
+    public void testFindLockPessimisticForceIncrement() {
+        getLog().info("---> testFindLockPessimisticForceIncrement()");
+        commonTestSequence(
+            LockModeType.PESSIMISTIC_FORCE_INCREMENT,
+            2,
+            0,
+            commonSelectForUpdate,
+            null,
+            commonSelectForUpdate,
+            null
+        );
+    }
+    
+    // TODO:
+    @AllowFailure(msg="OPENJPA-924 is preventing RR behavior: pessimistic lock "
+        + "blocked read on thread 2, once thread-1 commit, thread-2 returns "
+        + "with pre-thread 1 committed data. hence causing an "
+        + "OptimisticLockException. Disable FinderCache to workaround the " 
+        + "problem.")
+    public void testConcurrentThread1ReadTest() {
+        getLog().info("---> testConcurrentThread1ReadTest()");
+        String baseFirstName;
+        String t1FirstName;
+        String t2FirstName;
+        
+        //=======================================================
+        // Thread 1: Read           commit
+        // Thread 2: Optimistic     commit
+        baseFirstName = 1 + TxtLockRead + TxtCommit 
+                      + 2 + TxtLockOptimistic + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 2, t2FirstName,
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+            LockModeType.READ,
+            t1FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.OPTIMISTIC, 
+            t2FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+        //=======================================================
+        // Thread 1: Read           rollback
+        // Thread 2: Optimistic     commit
+        baseFirstName = 1 + TxtLockRead + TxtRollback 
+                      + 2 + TxtLockOptimistic + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 1, t2FirstName, 
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+            LockModeType.READ,
+            t1FirstName,
+            CommitAction.Rollback,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.OPTIMISTIC, 
+            t2FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+
+        //=======================================================
+        // Thread 1: Optimistic     commit
+        // Thread 2: Optimistic     commit
+        baseFirstName = 1 + TxtLockOptimistic + TxtCommit
+                      + 2 + TxtLockOptimistic + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 2, t2FirstName, 
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+            LockModeType.OPTIMISTIC,
+            t1FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.OPTIMISTIC, 
+            t2FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+        //=======================================================
+        // Thread 1: Optimistic     rollback
+        // Thread 2: Optimistic     commit
+        baseFirstName = 1 + TxtLockOptimistic + TxtRollback 
+                      + 2 + TxtLockOptimistic + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 1, t2FirstName, 
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+            LockModeType.OPTIMISTIC,
+            t1FirstName,
+            CommitAction.Rollback,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.OPTIMISTIC, 
+            t2FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+        //=======================================================
+        // Thread 1: Optimistic                 commit
+        // Thread 2: Optimistic_Force_Increment commit
+        baseFirstName = 1 + TxtLockOptimistic + TxtCommit
+                      + 2 + TxtLockOptimisticForceInc + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 2, t2FirstName, 
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+           LockModeType.OPTIMISTIC,
+            t1FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.OPTIMISTIC_FORCE_INCREMENT, 
+            t2FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+        //=======================================================
+        // Thread 1: Optimistic                 rollback
+        // Thread 2: Optimistic_Force_Increment commit
+        baseFirstName = 1 + TxtLockOptimistic + TxtRollback
+                      + 2 + TxtLockOptimisticForceInc + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 1, t2FirstName, 
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+            LockModeType.OPTIMISTIC,
+            t1FirstName,
+            CommitAction.Rollback,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.OPTIMISTIC_FORCE_INCREMENT, 
+            t2FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+        //=======================================================
+        // Thread 1: Optimistic             commit
+        // Thread 2: Pessimistic_Read       commit
+        baseFirstName = 1 + TxtLockOptimistic + TxtCommit
+                      + 2 + TxtLockPessimisticRead + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 2, t2FirstName, 
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+            LockModeType.OPTIMISTIC,
+            t1FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.PESSIMISTIC, 
+// TODO:            LockModeType.PESSIMISTIC_READ, 
+            t2FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+        //=======================================================
+        // Thread 1: Optimistic             rollback
+        // Thread 2: Pessimistic_Read      commit
+        baseFirstName = 1 + TxtLockOptimistic + TxtRollback
+                      + 2 + TxtLockPessimisticRead + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 1, t2FirstName, 
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+            LockModeType.OPTIMISTIC,
+            t1FirstName,
+            CommitAction.Rollback,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.PESSIMISTIC, 
+// TODO:            LockModeType.PESSIMISTIC_READ, 
+            t2FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+        //=======================================================
+        // Thread 1: Optimistic             commit
+        // Thread 2: Pessimistic_Write      commit
+        baseFirstName = 1 + TxtLockOptimistic + TxtCommit
+                      + 2 + TxtLockPessimisticWrite + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 2, t2FirstName, 
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+            LockModeType.OPTIMISTIC,
+            t1FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.PESSIMISTIC, 
+// TODO:            LockModeType.PESSIMISTIC_WRITE, 
+            t2FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+        //=======================================================
+        // Thread 1: Optimistic             rollback
+        // Thread 2: Pessimistic_Write      commit
+        baseFirstName = 1 + TxtLockOptimistic + TxtRollback
+                      + 2 + TxtLockPessimisticWrite + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 1, t2FirstName, 
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+            LockModeType.OPTIMISTIC,
+            t1FirstName,
+            CommitAction.Rollback,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.PESSIMISTIC, 
+// TODO:            LockModeType.PESSIMISTIC_WRITE, 
+            t2FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+        //=======================================================
+        // Thread 1: Optimistic                     commit
+        // Thread 2: Pessimistic_Force_Increment    commit
+        baseFirstName = 1 + TxtLockOptimistic + TxtCommit
+                      + 2 + TxtLockPessimisticForceInc + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 2, t2FirstName, 
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+            LockModeType.OPTIMISTIC,
+            t1FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.PESSIMISTIC_FORCE_INCREMENT,
+            t2FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+        //=======================================================
+        // Thread 1: Optimistic                     rollback
+        // Thread 2: Pessimistic_Force_Increment    commit
+        baseFirstName = 1 + TxtLockOptimistic + TxtRollback
+                      + 2 + TxtLockPessimisticForceInc + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 1, t2FirstName, 
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+            LockModeType.OPTIMISTIC,
+            t1FirstName,
+            CommitAction.Rollback,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.PESSIMISTIC_FORCE_INCREMENT,
+            t2FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+    }
+        
+    // TODO:
+    @AllowFailure(msg="OPENJPA-924 is preventing RR behavior: pessimistic lock "
+        + "blocked read on thread 2, once thread-1 commit, thread-2 returns "
+        + "with pre-thread 1 committed data. hence causing an "
+        + "OptimisticLockException. Disable FinderCache to workaround the " 
+        + "problem.")
+    public void testConcurrentThread1WriteTest() {
+        getLog().info("---> testConcurrentThread1WriteTest()");
+        String baseFirstName;
+        String t1FirstName;
+        String t2FirstName;
+        
+        //=======================================================
+        // Thread 1: Write          commit
+        // Thread 2: Optimistic     commit
+        baseFirstName = 1 + TxtLockWrite + TxtCommit
+                      + 2 + TxtLockOptimistic + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 2, t2FirstName,
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+            LockModeType.WRITE,
+            t1FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.OPTIMISTIC, 
+            t2FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+        //=======================================================
+        // Thread 1: Write          rollback
+        // Thread 2: Optimistic     commit
+        baseFirstName = 1 + TxtLockWrite + TxtRollback
+                      + 2 + TxtLockOptimistic + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 1, t2FirstName, 
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+            LockModeType.WRITE,
+            t1FirstName,
+            CommitAction.Rollback,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.OPTIMISTIC, 
+            t2FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+
+        //=======================================================
+        // Thread 1: Optimistic_Force_Increment commit
+        // Thread 2: Optimistic                 commit
+        baseFirstName = 1 + TxtLockOptimisticForceInc + TxtCommit
+                      + 2 + TxtLockOptimistic + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 2, t2FirstName, 
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+            LockModeType.OPTIMISTIC_FORCE_INCREMENT,
+            t1FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.OPTIMISTIC, 
+            t2FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+        //=======================================================
+        // Thread 1: Optimistic_Force_Increment rollback
+        // Thread 2: Optimistic                 commit
+        baseFirstName = 1 + TxtLockOptimisticForceInc + TxtRollback
+                      + 2 + TxtLockOptimistic + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 1, t2FirstName, 
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+            LockModeType.OPTIMISTIC_FORCE_INCREMENT,
+            t1FirstName,
+            CommitAction.Rollback,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.OPTIMISTIC, 
+            t2FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+        //=======================================================
+        // Thread 1: Optimistic_Force_Increment commit
+        // Thread 2: Optimistic_Force_Increment commit
+        baseFirstName = 1 + TxtLockOptimisticForceInc + TxtCommit
+                      + 2 + TxtLockOptimisticForceInc + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 2, t2FirstName, 
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+            LockModeType.OPTIMISTIC_FORCE_INCREMENT,
+            t1FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.OPTIMISTIC_FORCE_INCREMENT, 
+            t2FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+        //=======================================================
+        // Thread 1: Optimistic_Force_Increment rollback
+        // Thread 2: Optimistic_Force_Increment commit
+        baseFirstName = 1 + TxtLockOptimisticForceInc + TxtRollback
+                      + 2 + TxtLockOptimisticForceInc + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 1, t2FirstName, 
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+            LockModeType.OPTIMISTIC_FORCE_INCREMENT,
+            t1FirstName,
+            CommitAction.Rollback,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.OPTIMISTIC_FORCE_INCREMENT, 
+            t2FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+        //=======================================================
+        // Thread 1: Optimistic_Force_Increment commit
+        // Thread 2: Pessimistic_Read           commit
+        baseFirstName = 1 + TxtLockOptimisticForceInc + TxtCommit
+                      + 2 + TxtLockPessimisticRead + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 2, t2FirstName, 
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+            LockModeType.OPTIMISTIC_FORCE_INCREMENT,
+            t1FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.PESSIMISTIC, 
+// TODO:            LockModeType.PESSIMISTIC_READ, 
+            t2FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+        //=======================================================
+        // Thread 1: Optimistic_Force_Increment rollback
+        // Thread 2: Pessimistic_Read           commit
+        baseFirstName = 1 + TxtLockOptimisticForceInc + TxtRollback
+                      + 2 + TxtLockPessimisticRead + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 1, t2FirstName, 
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+            LockModeType.OPTIMISTIC_FORCE_INCREMENT,
+            t1FirstName,
+            CommitAction.Rollback,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.PESSIMISTIC, 
+// TODO:            LockModeType.PESSIMISTIC_READ, 
+            t2FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+        //=======================================================
+        // Thread 1: Optimistic_Force_Increment commit
+        // Thread 2: Pessimistic_Write          commit
+        baseFirstName = 1 + TxtLockOptimisticForceInc + TxtCommit
+                      + 2 + TxtLockPessimisticWrite + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 2, t2FirstName, 
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+            LockModeType.OPTIMISTIC_FORCE_INCREMENT,
+            t1FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.PESSIMISTIC, 
+// TODO:            LockModeType.PESSIMISTIC_WRITE, 
+            t2FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+        //=======================================================
+        // Thread 1: Optimistic_Force_Increment rollback
+        // Thread 2: Pessimistic_Write          commit
+        baseFirstName = 1 + TxtLockOptimisticForceInc + TxtRollback
+                      + 2 + TxtLockPessimisticWrite + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 1, t2FirstName, 
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+            LockModeType.OPTIMISTIC_FORCE_INCREMENT,
+            t1FirstName,
+            CommitAction.Rollback,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.PESSIMISTIC, 
+// TODO:            LockModeType.PESSIMISTIC_WRITE, 
+            t2FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+        //=======================================================
+        // Thread 1: Optimistic_Force_Increment  commit
+        // Thread 2: Pessimistic_Force_Increment commit
+        baseFirstName = 1 + TxtLockOptimisticForceInc + TxtCommit
+                      + 2 + TxtLockPessimisticForceInc + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 2, t2FirstName, 
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+            LockModeType.OPTIMISTIC_FORCE_INCREMENT,
+            t1FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.PESSIMISTIC_FORCE_INCREMENT,
+            t2FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+        //=======================================================
+        // Thread 1: Optimistic_Force_Increment  rollback
+        // Thread 2: Pessimistic_Force_Increment commit
+        baseFirstName = 1 + TxtLockOptimisticForceInc + TxtRollback
+                      + 2 + TxtLockPessimisticForceInc + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 1, t2FirstName, 
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+            LockModeType.OPTIMISTIC_FORCE_INCREMENT,
+            t1FirstName,
+            CommitAction.Rollback,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.PESSIMISTIC_FORCE_INCREMENT,
+            t2FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+    }
+        
+    // TODO:
+    @AllowFailure(msg="OPENJPA-924 is preventing RR behavior: pessimistic lock "
+        + "blocked read on thread 2, once thread-1 commit, thread-2 returns "
+        + "with pre-thread 1 committed data. hence causing an "
+        + "OptimisticLockException. Disable FinderCache to workaround the " 
+        + "problem.")
+    public void testConcurrentThread1PessimisticReadTest() {
+        getLog().info("---> testConcurrentThread1PessimisticReadTest()");
+        String baseFirstName;
+        String t1FirstName;
+        String t2FirstName;
+        
+        //=======================================================
+        // Thread 1: Pessimistic_Read    commit
+        // Thread 2: Optimistic     commit
+        baseFirstName = 1 + TxtLockPessimisticRead + TxtCommit
+                      + 2 + TxtLockOptimistic + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 2, t2FirstName,
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+// TODO:            LockModeType.PESSIMISTIC_READ,
+            LockModeType.PESSIMISTIC,
+            t1FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.OPTIMISTIC, 
+            t2FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+        //=======================================================
+        // Thread 1: Pessimistic_Read               rollback
+        // Thread 2: Optimistic     commit
+        baseFirstName = 1 + TxtLockPessimisticRead + TxtRollback
+                      + 2 + TxtLockOptimistic + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 1, t2FirstName, 
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+// TODO:          LockModeType.PESSIMISTIC_READ,
+            LockModeType.PESSIMISTIC,
+            t1FirstName,
+            CommitAction.Rollback,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.OPTIMISTIC, 
+            t2FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+
+        //=======================================================
+        // Thread 1: Pessimistic_Read    commit
+        // Thread 2: Read     commit
+        baseFirstName = 1 + TxtLockPessimisticRead + TxtCommit
+                      + 2 + TxtLockRead + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 2, t2FirstName, 
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+// TODO:          LockModeType.PESSIMISTIC_READ,
+            LockModeType.PESSIMISTIC,
+            t1FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.READ, 
+            t2FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+        //=======================================================
+        // Thread 1: Pessimistic_Read               rollback
+        // Thread 2: Read                           commit
+        baseFirstName = 1 + TxtLockPessimisticRead + TxtRollback
+                      + 2 + TxtLockRead + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 1, t2FirstName, 
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+// TODO:          LockModeType.PESSIMISTIC_READ,
+            LockModeType.PESSIMISTIC,
+            t1FirstName,
+            CommitAction.Rollback,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.READ, 
+            t2FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+        //=======================================================
+        // Thread 1: Pessimistic_Read    commit
+        // Thread 2: Optimistic_Force_Increment commit
+        baseFirstName = 1 + TxtLockPessimisticRead + TxtCommit
+                      + 2 + TxtLockOptimisticForceInc + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 2, t2FirstName, 
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+// TODO:          LockModeType.PESSIMISTIC_READ,
+            LockModeType.PESSIMISTIC,
+            t1FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.OPTIMISTIC_FORCE_INCREMENT, 
+            t2FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+        //=======================================================
+        // Thread 1: Pessimistic_Read               rollback
+        // Thread 2: Optimistic_Force_Increment commit
+        baseFirstName = 1 + TxtLockPessimisticRead + TxtRollback
+                      + 2 + TxtLockOptimisticForceInc + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 1, t2FirstName, 
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+// TODO:          LockModeType.PESSIMISTIC_READ,
+            LockModeType.PESSIMISTIC,
+            t1FirstName,
+            CommitAction.Rollback,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.OPTIMISTIC_FORCE_INCREMENT, 
+            t2FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+        //=======================================================
+        // Thread 1: Pessimistic_Read    commit
+        // Thread 2: Pessimistic_Read       commit
+        baseFirstName = 1 + TxtLockPessimisticRead + TxtCommit
+                      + 2 + TxtLockPessimisticRead + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 2, t2FirstName, 
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+// TODO:          LockModeType.PESSIMISTIC_READ,
+            LockModeType.PESSIMISTIC,
+            t1FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.PESSIMISTIC, 
+// TODO:            LockModeType.PESSIMISTIC_READ, 
+            t2FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+        //=======================================================
+        // Thread 1: Pessimistic_Read               rollback
+        // Thread 2: Pessimistic_Read      commit
+        baseFirstName = 1 + TxtLockPessimisticRead + TxtRollback
+                      + 2 + TxtLockPessimisticRead + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 1, t2FirstName, 
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+// TODO:          LockModeType.PESSIMISTIC_READ,
+            LockModeType.PESSIMISTIC,
+            t1FirstName,
+            CommitAction.Rollback,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.PESSIMISTIC, 
+// TODO:            LockModeType.PESSIMISTIC_READ, 
+            t2FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+        //=======================================================
+        // Thread 1: Pessimistic_Read    commit
+        // Thread 2: Pessimistic_Write      commit
+        baseFirstName = 1 + TxtLockPessimisticRead + TxtCommit
+                      + 2 + TxtLockPessimisticWrite + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 2, t2FirstName, 
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+// TODO:          LockModeType.PESSIMISTIC_READ,
+            LockModeType.PESSIMISTIC,
+            t1FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.PESSIMISTIC, 
+// TODO:            LockModeType.PESSIMISTIC_WRITE, 
+            t2FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+        //=======================================================
+        // Thread 1: Pessimistic_Read               rollback
+        // Thread 2: Pessimistic_Write      commit
+        baseFirstName = 1 + TxtLockPessimisticRead + TxtRollback
+                      + 2 + TxtLockPessimisticWrite + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 1, t2FirstName, 
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+// TODO:          LockModeType.PESSIMISTIC_READ,
+            LockModeType.PESSIMISTIC,
+            t1FirstName,
+            CommitAction.Rollback,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.PESSIMISTIC, 
+// TODO:            LockModeType.PESSIMISTIC_WRITE, 
+            t2FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+        //=======================================================
+        // Thread 1: Pessimistic_Read    commit
+        // Thread 2: Pessimistic_Force_Increment    commit
+        baseFirstName = 1 + TxtLockPessimisticRead + TxtCommit
+                      + 2 + TxtLockPessimisticForceInc + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 2, t2FirstName, 
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+// TODO:          LockModeType.PESSIMISTIC_READ,
+            LockModeType.PESSIMISTIC,
+            t1FirstName, 
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.PESSIMISTIC_FORCE_INCREMENT, 
+            t2FirstName, 
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+        //=======================================================
+        // Thread 1: Pessimistic_Read               rollback
+        // Thread 2: Pessimistic_Force_Increment    commit
+        baseFirstName = 1 + TxtLockPessimisticRead + TxtRollback
+                      + 2 + TxtLockPessimisticForceInc + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 1, t2FirstName, 
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+// TODO:          LockModeType.PESSIMISTIC_READ,
+            LockModeType.PESSIMISTIC,
+            t1FirstName, 
+            CommitAction.Rollback,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.PESSIMISTIC_FORCE_INCREMENT, 
+            t2FirstName, 
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+    }
+
+    // TODO:
+    @AllowFailure(msg="OPENJPA-924 is preventing RR behavior: pessimistic lock "
+        + "blocked read on thread 2, once thread-1 commit, thread-2 returns "
+        + "with pre-thread 1 committed data. hence causing an "
+        + "OptimisticLockException. Disable FinderCache to workaround the " 
+        + "problem.")
+    public void testConcurrentThread1PessimisticForceIncTest() {
+        getLog().info("---> testConcurrentThread1PessimisticForceIncTest()");
+        String baseFirstName;
+        String t1FirstName;
+        String t2FirstName;
+        
+        //=======================================================
+        // Thread 1: Pessimistic_Force_Increment    commit
+        // Thread 2: Optimistic     commit
+        baseFirstName = 1 + TxtLockPessimisticForceInc + TxtCommit
+                      + 2 + TxtLockOptimistic + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 2, t2FirstName,
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+            LockModeType.PESSIMISTIC_FORCE_INCREMENT,
+            t1FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.OPTIMISTIC, 
+            t2FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+        //=======================================================
+        // Thread 1: Pessimistic_Force_Increment    rollback
+        // Thread 2: Optimistic     commit
+        baseFirstName = 1 + TxtLockPessimisticForceInc + TxtRollback
+                      + 2 + TxtLockOptimistic + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 1, t2FirstName, 
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+            LockModeType.PESSIMISTIC_FORCE_INCREMENT,
+            t1FirstName,
+            CommitAction.Rollback,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.OPTIMISTIC, 
+            t2FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+
+        //=======================================================
+        // Thread 1: Pessimistic_Force_Increment    commit
+        // Thread 2: Read     commit
+        baseFirstName = 1 + TxtLockPessimisticForceInc + TxtCommit
+                      + 2 + TxtLockRead + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 2, t2FirstName, 
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+            LockModeType.PESSIMISTIC_FORCE_INCREMENT,
+            t1FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.READ, 
+            t2FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+        //=======================================================
+        // Thread 1: Pessimistic_Force_Increment    rollback
+        // Thread 2: Read                           commit
+        baseFirstName = 1 + TxtLockPessimisticForceInc + TxtRollback
+                      + 2 + TxtLockRead + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 1, t2FirstName, 
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+            LockModeType.PESSIMISTIC_FORCE_INCREMENT,
+            t1FirstName,
+            CommitAction.Rollback,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.READ, 
+            t2FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+        //=======================================================
+        // Thread 1: Pessimistic_Force_Increment    commit
+        // Thread 2: Optimistic_Force_Increment commit
+        baseFirstName = 1 + TxtLockPessimisticForceInc + TxtCommit
+                      + 2 + TxtLockOptimisticForceInc + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 2, t2FirstName, 
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+           LockModeType.PESSIMISTIC_FORCE_INCREMENT,
+            t1FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.OPTIMISTIC_FORCE_INCREMENT, 
+            t2FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+        //=======================================================
+        // Thread 1: Pessimistic_Force_Increment    rollback
+        // Thread 2: Optimistic_Force_Increment commit
+        baseFirstName = 1 + TxtLockPessimisticForceInc + TxtRollback
+                      + 2 + TxtLockOptimisticForceInc + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 1, t2FirstName, 
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+            LockModeType.PESSIMISTIC_FORCE_INCREMENT,
+            t1FirstName,
+            CommitAction.Rollback,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.OPTIMISTIC_FORCE_INCREMENT, 
+            t2FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+        //=======================================================
+        // Thread 1: Pessimistic_Force_Increment    commit
+        // Thread 2: Pessimistic_Read       commit
+        baseFirstName = 1 + TxtLockPessimisticForceInc + TxtCommit
+                      + 2 + TxtLockPessimisticRead + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 2, t2FirstName, 
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+            LockModeType.PESSIMISTIC_FORCE_INCREMENT,
+            t1FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.PESSIMISTIC, 
+// TODO:            LockModeType.PESSIMISTIC_READ, 
+            t2FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+        //=======================================================
+        // Thread 1: Pessimistic_Force_Increment    rollback
+        // Thread 2: Pessimistic_Read      commit
+        baseFirstName = 1 + TxtLockPessimisticForceInc + TxtRollback
+                      + 2 + TxtLockPessimisticRead + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 1, t2FirstName, 
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+            LockModeType.PESSIMISTIC_FORCE_INCREMENT,
+            t1FirstName,
+            CommitAction.Rollback,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.PESSIMISTIC, 
+// TODO:            LockModeType.PESSIMISTIC_READ, 
+            t2FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+        //=======================================================
+        // Thread 1: Pessimistic_Force_Increment    commit
+        // Thread 2: Pessimistic_Write      commit
+        baseFirstName = 1 + TxtLockPessimisticForceInc + TxtCommit
+                      + 2 + TxtLockPessimisticWrite + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 2, t2FirstName, 
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+            LockModeType.PESSIMISTIC_FORCE_INCREMENT,
+            t1FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.PESSIMISTIC, 
+// TODO:            LockModeType.PESSIMISTIC_WRITE, 
+            t2FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+        //=======================================================
+        // Thread 1: Pessimistic_Force_Increment    rollback
+        // Thread 2: Pessimistic_Write      commit
+        baseFirstName = 1 + TxtLockPessimisticForceInc + TxtRollback
+                      + 2 + TxtLockPessimisticWrite + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 1, t2FirstName, 
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+            LockModeType.PESSIMISTIC_FORCE_INCREMENT,
+            t1FirstName,
+            CommitAction.Rollback,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.PESSIMISTIC, 
+// TODO:            LockModeType.PESSIMISTIC_WRITE, 
+            t2FirstName,
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+        //=======================================================
+        // Thread 1: Pessimistic_Force_Increment    commit
+        // Thread 2: Pessimistic_Force_Increment    commit
+        baseFirstName = 1 + TxtLockPessimisticForceInc + TxtCommit
+                      + 2 + TxtLockPessimisticForceInc + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 2, t2FirstName, 
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+            LockModeType.PESSIMISTIC_FORCE_INCREMENT, 
+            t1FirstName, 
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.PESSIMISTIC_FORCE_INCREMENT, 
+            t2FirstName, 
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+        //=======================================================
+        // Thread 1: Pessimistic_Force_Increment    rollback
+        // Thread 2: Pessimistic_Force_Increment    commit
+        baseFirstName = 1 + TxtLockPessimisticForceInc + TxtRollback
+                      + 2 + TxtLockPessimisticForceInc + TxtCommit; 
+        t1FirstName = TxtThread1 + baseFirstName; 
+        t2FirstName = TxtThread2 + baseFirstName; 
+        concurrentLockingTest(
+            1, 1, t2FirstName, 
+            ThreadToRunFirst.RunThread1,
+            ThreadToResumeFirst.ResumeThread1,
+            
+            LockModeType.PESSIMISTIC_FORCE_INCREMENT, 
+            t1FirstName, 
+            CommitAction.Rollback,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null,
+            
+            LockModeType.PESSIMISTIC_FORCE_INCREMENT, 
+            t2FirstName, 
+            CommitAction.Commit,
+            RollbackAction.NoRolledback,
+            null, 
+            MethodToCall.Find,
+            null
+        );
+    }
+}

Propchange: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/lockmgr/TestPessimisticLockManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/AllowFailure.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/AllowFailure.java?rev=747489&r1=747488&r2=747489&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/AllowFailure.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/AllowFailure.java Tue Feb 24 18:48:09 2009
@@ -34,4 +34,5 @@
 @Retention(RUNTIME)
 public @interface AllowFailure {
     boolean value() default true;
+    String msg() default "";
 }

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/PersistenceTestCase.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/PersistenceTestCase.java?rev=747489&r1=747488&r2=747489&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/PersistenceTestCase.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/PersistenceTestCase.java Tue Feb 24 18:48:09 2009
@@ -449,8 +449,11 @@
         try {
             super.runBare();
         } catch (Throwable t) {
-            if (allowFailure()) {
-                System.err.println("*** FAILED (but ignored):" + this);
+            String allowFailureMsg = getAllowFailureMsg(); 
+            if ( allowFailureMsg != null ) {
+                System.err.println("*** FAILED (but ignored): " + this);
+                System.err.println("***              Reason : " 
+                    + allowFailureMsg);
                 System.err.println("Stacktrace of failure");
                 t.printStackTrace();
             } else {
@@ -464,12 +467,12 @@
      * @AllowFailure. Method level annotation has higher precedence than Class
      * level annotation.
      */
-    protected boolean allowFailure() {
+    protected String getAllowFailureMsg() {
 		try {
             Method runMethod = getClass().getMethod(getName(), (Class[])null);
             AllowFailure anno = runMethod.getAnnotation(AllowFailure.class);
 	    	if (anno != null)
-	    		return anno.value();
+	    		return anno.value() ? anno.msg() : null;
 		} catch (SecurityException e) {
 			//ignore
 		} catch (NoSuchMethodException e) {
@@ -477,8 +480,8 @@
 		}
 		AllowFailure anno = getClass().getAnnotation(AllowFailure.class);
     	if (anno != null) 
-            return anno.value();
-    	return false;
+            return anno.value() ? anno.msg() : null;
+    	return null;
     }
     
     private static class FixedMap extends LinkedHashMap<EMFKey, OpenJPAEntityManagerFactorySPI> {

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/SQLListenerTestCase.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/SQLListenerTestCase.java?rev=747489&r1=747488&r2=747489&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/SQLListenerTestCase.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/SQLListenerTestCase.java Tue Feb 24 18:48:09 2009
@@ -18,9 +18,9 @@
  */
 package org.apache.openjpa.persistence.test;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
-import java.util.ArrayList;
 
 import org.apache.openjpa.lib.jdbc.AbstractJDBCListener;
 import org.apache.openjpa.lib.jdbc.JDBCEvent;
@@ -35,8 +35,7 @@
     extends SingleEMFTestCase {
     private static String _nl = System.getProperty("line.separator");
     protected List<String> sql = new ArrayList<String>();
-    protected int sqlCount;
-    
+
     @Override
     public void setUp(Object... props) {
         Object[] copy = new Object[props.length + 2];
@@ -67,16 +66,15 @@
      * @param sqlExp the SQL expression. E.g., "SELECT BADCOLUMN .*"
      */
     public void assertNotSQL(String sqlExp) {
-        boolean failed = false;
-
         for (String statement : sql) {
-            if (statement.matches(sqlExp))
-                failed = true;
+            if (statement.matches(sqlExp)) {
+                fail("Regular expression\r\n <"
+                    + sqlExp
+                    + ">\r\n should not have been executed in SQL statements:"
+                    + "\r\n" + toString(sql));
+                break;
+            }
         }
-
-        if (failed)
-            fail("Regular expression\r\n <" + sqlExp + ">\r\n should not have"
-                    + " been executed in SQL statements: \r\n" + toString(sql));
     }
 
     /**
@@ -91,24 +89,119 @@
         }
 
         fail("Expected regular expression\r\n <" + sqlExp + ">\r\n to be"
-                + " contained in SQL statements: \r\n" + toString(sql));
+            + " contained in SQL statements: \r\n" + toString(sql));
+    }
+
+    /**
+     * Confirm the list of expected SQL expressions have been executed in the
+     * order specified. I.e. additional SQL statements can be executed in
+     * between expected SQLs.
+     * 
+     * @param expected
+     *            SQL expressions. E.g., ("SELECT FOO .*", "UPDATE .*")
+     */
+    public void assertAllSQLInOrder(String... expected) {
+        assertSQLInOrder(false, expected);
+    }
+
+    /**
+     * Confirm the list of expected SQL expressions have been executed in the
+     * exact number and order specified.
+     * 
+     * @param expected
+     *            SQL expressions. E.g., ("SELECT FOO .*", "UPDATE .*")
+     */
+    public void assertAllExactSQLInOrder(String... expected) {
+        assertSQLInOrder(true, expected);
+    }
+
+    private void assertSQLInOrder(boolean exact, String... expected) {
+        boolean match = false;
+        int sqlSize = sql.size();
+        if (expected.length <= sqlSize) {
+            int hits = 0;
+            for (String executedSQL : sql) {
+                if (executedSQL.matches(expected[hits])) {
+                    if (++hits == expected.length)
+                        break;
+                }
+            }
+            match = hits == (exact ? sqlSize : expected.length);
+        }
+
+        if (!match) {
+            StringBuilder sb = new StringBuilder();
+            sb.append("Did not find SQL in expected order : ").append(_nl);
+            for (String s : expected) {
+                sb.append(s).append(_nl);
+            }
+
+            sb.append("SQL Statements issued : ");
+            for (String s : sql) {
+                sb.append(s).append(_nl);
+            }
+            fail(sb.toString());
+        }
+    }
+
+    /**
+     * Confirm the list of expected SQL expressions have executed in any order.
+     * 
+     * @param expected
+     *            SQL expressions. E.g., ("SELECT FOO .*", "UPDATE .*")
+     */
+    public void assertAllSQLAnyOrder(String... expected) {
+        for (String statement : expected) {
+            assertSQL(statement);
+        }
+    }
+
+    /**
+     * Confirm the list of expected SQL expressions have not executed in any
+     * order.
+     * 
+     * @param expected
+     *            SQL expressions. E.g., ("SELECT FOO .*", "UPDATE .*")
+     */
+    public void assertNoneSQLAnyOrder(String... expected) {
+        for (String statement : expected) {
+            assertNotSQL(statement);
+        }
+    }
+
+    /**
+     * Confirm the any of expected SQL expressions have executed in any order.
+     * 
+     * @param expected
+     *            SQL expressions. E.g., ("SELECT FOO .*", "UPDATE .*")
+     */
+    public void assertAnySQLAnyOrder(String... expected) {
+        for (String sqlExp : expected) {
+            for (String statement : sql) {
+                if (statement.matches(sqlExp))
+                    return;
+            }
+        }
+        fail("Expected regular expression\r\n <"
+            + toString(Arrays.asList(expected)) + ">\r\n to be"
+            + " contained in SQL statements: \r\n" + toString(sql));
     }
     
     /**
      * Gets the number of SQL issued since last reset.
      */
     public int getSQLCount() {
-    	return sqlCount;
+        return sql.size();
     }
     
     /**
      * Resets SQL count.
      * @return number of SQL counted since last reset.
      */
-    public int resetSQLCount() {
-    	int tmp = sqlCount;
-    	sqlCount = 0;
-    	return tmp;
+    public int resetSQL() {
+        int tmp = sql.size();
+        sql.clear();
+        return tmp;
     }
 
     public String toString(List<String> list) {
@@ -125,32 +218,50 @@
         public void beforeExecuteStatement(JDBCEvent event) {
             if (event.getSQL() != null && sql != null) {
                 sql.add(event.getSQL());
-                sqlCount++;
-            }
-		}
-	}
-    
-    public void assertSQLOrder(String... expected) {
-        int hits = 0;
-
-        for (String executedSQL : sql) {
-            if (executedSQL.matches(expected[hits])) {
-                hits++;
             }
         }
+    }
 
-        if (hits != expected.length) {
-            StringBuilder sb = new StringBuilder();
-            sb.append("Did not find SQL in expected order : ").append(_nl);
-            for (String s : expected) {
-                sb.append(s).append(_nl);
-            }
+    public enum SQLAssertType {
+        SQL, NotSQL, ContainsSQL, AllSQLInOrder, AllExactSQLInOrder, 
+        AllSQLAnyOrder, NoneSQLAnyOrder, AnySQLAnyOrder
+    };
+
+    public class SQLAssertions {
+        SQLAssertType type;
+        String[] template;
+
+        public SQLAssertions(SQLAssertType type, String... template) {
+            this.type = type;
+            this.template = template;
+        }
 
-            sb.append("SQL Statements issued : ");
-            for (String s : sql) {
-                sb.append(s).append(_nl);
+        public void validate() {
+            switch (type) {
+            case SQL:
+                assertSQL(template[0]);
+                break;
+            case NotSQL:
+                assertNotSQL(template[0]);
+                break;
+            case ContainsSQL:
+                assertContainsSQL(template[0]);
+                break;
+            case AllSQLInOrder:
+                assertAllSQLInOrder(template);
+                break;
+            case AllExactSQLInOrder:
+                assertAllExactSQLInOrder(template);
+                break;
+            case AllSQLAnyOrder:
+                assertAllSQLAnyOrder(template);
+                break;
+            case AnySQLAnyOrder:
+                assertAnySQLAnyOrder(template);
+                break;
+            case NoneSQLAnyOrder:
+                assertNoneSQLAnyOrder(template);
             }
-            fail(sb.toString());
         }
     }
 }

Modified: openjpa/trunk/openjpa-persistence/pom.xml
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/pom.xml?rev=747489&r1=747488&r2=747489&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/pom.xml (original)
+++ openjpa/trunk/openjpa-persistence/pom.xml Tue Feb 24 18:48:09 2009
@@ -40,6 +40,11 @@
             <version>${pom.version}</version>
         </dependency>
         <dependency>
+            <groupId>org.apache.openjpa</groupId>
+            <artifactId>openjpa-jdbc</artifactId>
+            <version>${pom.version}</version>
+        </dependency>
+        <dependency>
             <groupId>org.apache.geronimo.specs</groupId>
             <artifactId>geronimo-jpa_2.0_spec</artifactId>
         </dependency>

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java?rev=747489&r1=747488&r2=747489&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java Tue Feb 24 18:48:09 2009
@@ -28,6 +28,7 @@
 import java.io.ObjectOutputStream;
 import java.io.ObjectStreamClass;
 import java.lang.reflect.Array;
+import java.sql.Connection;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.EnumSet;
@@ -47,6 +48,8 @@
 import org.apache.openjpa.ee.ManagedRuntime;
 import org.apache.openjpa.enhance.PCEnhancer;
 import org.apache.openjpa.enhance.PCRegistry;
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
 import org.apache.openjpa.kernel.AbstractBrokerFactory;
 import org.apache.openjpa.kernel.Broker;
 import org.apache.openjpa.kernel.DelegatingBroker;
@@ -61,6 +64,8 @@
 import org.apache.openjpa.kernel.QueryLanguages;
 import org.apache.openjpa.kernel.Seq;
 import org.apache.openjpa.kernel.jpql.JPQLParser;
+import org.apache.openjpa.lib.conf.Configuration;
+import org.apache.openjpa.lib.conf.IntValue;
 import org.apache.openjpa.lib.util.Closeable;
 import org.apache.openjpa.lib.util.Localizer;
 import org.apache.openjpa.meta.ClassMetaData;
@@ -459,6 +464,26 @@
         return (T) _broker.find(oid, true, this);
     }
 
+    public <T> T find(Class<T> cls, Object oid, LockModeType mode) {
+        return find(cls, oid, mode, null);
+    }
+
+    @SuppressWarnings("unchecked")
+    public <T> T find(Class<T> cls, Object oid, LockModeType mode,
+        Map<String, Object> properties) {
+        assertNotCloseInvoked();
+        if (mode != LockModeType.NONE)
+            _broker.assertActiveTransaction();
+
+        boolean fcPushed = pushLockProperties(mode, properties);
+        try {
+            oid = _broker.newObjectId(cls, oid);
+            return (T) _broker.find(oid, true, this);
+        } finally {
+            popLockProperties(fcPushed);
+        }
+    }
+
     @SuppressWarnings("unchecked")
     public <T> T[] findAll(Class<T> cls, Object... oids) {
         if (oids.length == 0)
@@ -695,6 +720,23 @@
         _broker.refresh(entity, this);
     }
 
+    public void refresh(Object entity, LockModeType mode) {
+        refresh(entity, mode, null);
+    }
+
+    public void refresh(Object entity, LockModeType mode,
+        Map<String, Object> properties) {
+        assertNotCloseInvoked();
+        _broker.assertWriteOperation();
+
+        boolean fcPushed = pushLockProperties(mode, properties);
+        try {
+            _broker.refresh(entity, this);
+        } finally {
+            popLockProperties(fcPushed);
+        }
+    }
+
     public void refreshAll() {
         assertNotCloseInvoked();
         _broker.assertWriteOperation();
@@ -1049,6 +1091,20 @@
         _broker.lock(entity, toLockLevel(mode), timeout, this);
     }
 
+    public void lock(Object entity, LockModeType mode,
+        Map<String, Object> properties) {
+        assertNotCloseInvoked();
+        _broker.assertActiveTransaction();
+
+        boolean fcPushed = pushLockProperties(mode, properties);
+        try {
+            _broker.lock(entity, toLockLevel(mode), _broker
+                .getFetchConfiguration().getLockTimeout(), this);
+        } finally {
+            popLockProperties(fcPushed);
+        }
+    }
+
     public void lockAll(Collection entities) {
         assertNotCloseInvoked();
         _broker.lockAll(entities, this);
@@ -1071,23 +1127,38 @@
      * Translate our internal lock level to a javax.persistence enum value.
      */
     static LockModeType fromLockLevel(int level) {
-        if (level < LockLevels.LOCK_READ)
+        if (level < JPA2LockLevels.LOCK_OPTIMISTIC)
             return null;
-        if (level < LockLevels.LOCK_WRITE)
+        if (level < JPA2LockLevels.LOCK_OPTIMISTIC_FORCE_INCREMENT)
             return LockModeType.READ;
-        return LockModeType.WRITE;
+        if (level < JPA2LockLevels.LOCK_PESSIMISTIC_READ)
+            return LockModeType.WRITE;
+        if (level < JPA2LockLevels.LOCK_PESSIMISTIC_WRITE)
+            return LockModeType.PESSIMISTIC;
+// TODO:         return LockModeType.PESSIMISTIC_READ;
+        if (level < JPA2LockLevels.LOCK_PESSIMISTIC_FORCE_INCREMENT)
+            return LockModeType.PESSIMISTIC;
+// TODO:         return LockModeType.PESSIMISTIC_WRITE;
+        return LockModeType.PESSIMISTIC_FORCE_INCREMENT;
     }
 
     /**
      * Translate the javax.persistence enum value to our internal lock level.
      */
     static int toLockLevel(LockModeType mode) {
-        if (mode == null)
+        if (mode == null || mode == LockModeType.NONE)
             return LockLevels.LOCK_NONE;
-        if (mode == LockModeType.READ)
+        if (mode == LockModeType.READ || mode == LockModeType.OPTIMISTIC)
             return LockLevels.LOCK_READ;
-        if (mode == LockModeType.WRITE)
+        if (mode == LockModeType.WRITE
+            || mode == LockModeType.OPTIMISTIC_FORCE_INCREMENT)
             return LockLevels.LOCK_WRITE;
+// TODO:      if (mode == LockModeType.PESSIMISTIC_READ)
+// TODO:         return LockLevels.LOCK_PESSIMISTIC_READ;
+        if (mode == LockModeType.PESSIMISTIC)
+            return JPA2LockLevels.LOCK_PESSIMISTIC_WRITE;
+        if (mode == LockModeType.PESSIMISTIC_FORCE_INCREMENT)
+            return JPA2LockLevels.LOCK_PESSIMISTIC_FORCE_INCREMENT;
         throw new ArgumentException(mode.toString(), null, null, true);
     }
 
@@ -1430,19 +1501,7 @@
         return createQuery(jpql);
     }
 
-    public <T> T find(Class<T> entityClass, Object primaryKey, 
-    	LockModeType lockMode) {
-        throw new UnsupportedOperationException(
-            "JPA 2.0 - Method not yet implemented");
-    }
-
-    public <T> T find(Class<T> entityClass, Object primaryKey, 
-    	LockModeType lockMode, Map<String, Object> properties) {
-        throw new UnsupportedOperationException(
-            "JPA 2.0 - Method not yet implemented");
-    }
-
-    /* 
+    /*
      * @see javax.persistence.EntityManager#getProperties()
      * 
      * This does not return the password property.
@@ -1469,23 +1528,6 @@
         return _broker.getSupportedProperties();
     }
 
-    public void lock(Object entity, LockModeType lockMode, Map<String, 
-    	Object> properties) {
-        throw new UnsupportedOperationException(
-            "JPA 2.0 - Method not yet implemented");
-    }
-
-    public void refresh(Object entity, LockModeType lockMode) {
-        throw new UnsupportedOperationException(
-            "JPA 2.0 - Method not yet implemented");
-    }
-
-    public void refresh(Object entity, LockModeType lockMode, Map<String, 
-    	Object> properties) {
-        throw new UnsupportedOperationException(
-            "JPA 2.0 - Method not yet implemented");
-    }
-
     public <T> T unwrap(Class<T> cls) {
         throw new UnsupportedOperationException(
             "JPA 2.0 - Method not yet implemented");
@@ -1504,4 +1546,135 @@
         return _ret;
     }
 
+    private enum FetchConfigProperty {
+        LockTimeout, ReadLockLevel, WriteLockLevel
+    };
+
+    private boolean setFetchConfigProperty(FetchConfigProperty[] validProps,
+        Map<String, Object> properties) {
+        boolean fcPushed = false;
+        if (properties != null && properties.size() > 0) {
+            Configuration conf = _broker.getConfiguration();
+            Set<String> inKeys = properties.keySet();
+            for (String inKey : inKeys) {
+                for (FetchConfigProperty validProp : validProps) {
+                    String validPropStr = validProp.toString();
+                    Set<String> validPropKeys = conf
+                        .getPropertyKeys(validPropStr);
+
+                    if (validPropKeys.contains(inKey)) {
+                        FetchConfiguration fCfg = _broker
+                            .getFetchConfiguration();
+                        IntValue intVal = new IntValue(inKey);
+                        try {
+                            Object setValue = properties.get(inKey);
+                            if (setValue instanceof String) {
+                                intVal.setString((String) setValue);
+                            } else if (Number.class.isAssignableFrom(setValue
+                                .getClass())) {
+                                intVal.setObject(setValue);
+                            } else {
+                                intVal.setString(setValue.toString());
+                            }
+                            int value = intVal.get();
+                            switch (validProp) {
+                            case LockTimeout:
+                                if (!fcPushed) {
+                                    fCfg = _broker.pushFetchConfiguration();
+                                    fcPushed = true;
+                                }
+                                fCfg.setLockTimeout(value);
+                                break;
+                            case ReadLockLevel:
+                                if (value != LockLevels.LOCK_NONE
+                                    && value != fCfg.getReadLockLevel()) {
+                                    if (!fcPushed) {
+                                        fCfg = _broker.pushFetchConfiguration();
+                                        fcPushed = true;
+                                    }
+                                    fCfg.setReadLockLevel(value);
+                                }
+                                break;
+                            case WriteLockLevel:
+                                if (value != LockLevels.LOCK_NONE
+                                    && value != fCfg.getWriteLockLevel()) {
+                                    if (!fcPushed) {
+                                        fCfg = _broker.pushFetchConfiguration();
+                                        fcPushed = true;
+                                    }
+                                    fCfg.setWriteLockLevel(value);
+                                }
+                                break;
+                            }
+                        } catch (Exception e) {
+                            // silently ignore the property
+                        }
+                        break; // for(String inKey : inKeys)
+                    }
+                }
+            }
+        }
+        return fcPushed;
+    }
+
+    private boolean pushLockProperties(LockModeType mode,
+        Map<String, Object> properties) {
+        boolean fcPushed = false;
+        // handle properties in map first
+        if (properties != null) {
+            fcPushed = setFetchConfigProperty(new FetchConfigProperty[] {
+                FetchConfigProperty.LockTimeout,
+                FetchConfigProperty.ReadLockLevel,
+                FetchConfigProperty.WriteLockLevel }, properties);
+        }
+        // override with the specific lockMode, if needed.
+        int setReadLevel = toLockLevel(mode);
+        if (setReadLevel != JPA2LockLevels.LOCK_NONE) {
+            // Set overriden read lock level
+            FetchConfiguration fCfg = _broker.getFetchConfiguration();
+            int curReadLevel = fCfg.getReadLockLevel();
+            if (setReadLevel != curReadLevel) {
+                if (!fcPushed) {
+                    fCfg = _broker.pushFetchConfiguration();
+                    fcPushed = true;
+                }
+                fCfg.setReadLockLevel(setReadLevel);
+            }
+            // Set overriden isolation level for pessimistic-read/write
+            if (((JDBCConfiguration) _broker.getConfiguration())
+                .getDBDictionaryInstance().supportIsolationForUpdate()) {
+                switch (setReadLevel) {
+                case JPA2LockLevels.LOCK_PESSIMISTIC_READ:
+                    fcPushed = setIsolationForPessimisticLock(fCfg, fcPushed,
+                        Connection.TRANSACTION_REPEATABLE_READ);
+                    break;
+
+                case JPA2LockLevels.LOCK_PESSIMISTIC_WRITE:
+                case JPA2LockLevels.LOCK_PESSIMISTIC_FORCE_INCREMENT:
+                    fcPushed = setIsolationForPessimisticLock(fCfg, fcPushed,
+                        Connection.TRANSACTION_SERIALIZABLE);
+                    break;
+
+                default:
+                }
+            }
+        }
+        return fcPushed;
+    }
+
+    private boolean setIsolationForPessimisticLock(FetchConfiguration fCfg,
+        boolean fcPushed, int level) {
+        if (!fcPushed) {
+            fCfg = _broker.pushFetchConfiguration();
+            fcPushed = true;
+        }
+        ((JDBCFetchConfiguration) fCfg).setIsolation(level);
+        return fcPushed;
+    }
+
+    private void popLockProperties(boolean fcPushed) {
+        if (fcPushed) {
+            _broker.popFetchConfiguration();
+        }
+    }
 }

Added: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/JPA2LockLevels.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/JPA2LockLevels.java?rev=747489&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/JPA2LockLevels.java (added)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/JPA2LockLevels.java Tue Feb 24 18:48:09 2009
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.persistence;
+
+import org.apache.openjpa.kernel.LockLevels;
+
+/**
+ * Standard object lock levels.
+ *
+ * @author Albert Lee
+ * @since 2.0.0
+ */
+public interface JPA2LockLevels extends LockLevels{
+
+    /**
+     * Generic optimistic read lock level. Value of 10.
+     */
+    public static final int LOCK_OPTIMISTIC = LOCK_READ;
+
+    /**
+     * Generic optimistic write lock level. Value of 20.
+     */
+    public static final int LOCK_OPTIMISTIC_FORCE_INCREMENT = LOCK_WRITE;
+
+    /**
+     * Generic pessimistic read lock level. Value of 30.
+     */
+    public static final int LOCK_PESSIMISTIC_READ = 30;
+
+    /**
+     * Generic pessimistic write lock level. Value of 40.
+     */
+    public static final int LOCK_PESSIMISTIC_WRITE = 40;
+
+    /**
+     * Generic pessimistic force increment level. Value of 50.
+     */
+    public static final int LOCK_PESSIMISTIC_FORCE_INCREMENT = 50;
+
+}

Propchange: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/JPA2LockLevels.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message