Modified: openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/TestPessimisticLocks.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/TestPessimisticLocks.java?rev=884744&r1=884743&r2=884744&view=diff ============================================================================== --- openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/TestPessimisticLocks.java (original) +++ openjpa/trunk/openjpa-persistence-locking/src/test/java/org/apache/openjpa/persistence/lockmgr/TestPessimisticLocks.java Fri Nov 27 05:11:21 2009 @@ -28,6 +28,8 @@ import javax.persistence.Query; import javax.persistence.QueryTimeoutException; +import org.apache.openjpa.jdbc.conf.JDBCConfiguration; +import org.apache.openjpa.jdbc.sql.DBDictionary; import org.apache.openjpa.persistence.test.SQLListenerTestCase; /** @@ -35,9 +37,11 @@ */ public class TestPessimisticLocks extends SQLListenerTestCase { + private DBDictionary dict = null; + public void setUp() { setSupportedDatabases( -// org.apache.openjpa.jdbc.sql.DerbyDictionary.class, + org.apache.openjpa.jdbc.sql.DerbyDictionary.class, // org.apache.openjpa.jdbc.sql.OracleDictionary.class, org.apache.openjpa.jdbc.sql.DB2Dictionary.class); if (isTestsDisabled()) { @@ -48,6 +52,8 @@ String empTable = getMapping(Employee.class).getTable().getFullName(); String deptTable = getMapping(Department.class).getTable().getFullName(); + dict= ((JDBCConfiguration)emf.getConfiguration()).getDBDictionaryInstance(); + EntityManager em = null; try { em = emf.createEntityManager(); @@ -96,25 +102,110 @@ } /* - * Test a find with pessimistic lock after a query with pessimistic lock and expect PessimisticLockException. + * Test find with pessimistic lock after a query with pessimistic lock. */ - public void testFindWithLockTimeoutAfterQueryWithPessimisticLocks() { + public void testFindAfterQueryWithPessimisticLocks() { EntityManager em1 = emf.createEntityManager(); EntityManager em2 = emf.createEntityManager(); try { em1.getTransaction().begin(); + Query query = em1.createQuery( + "select e from Employee e where e.id < 10").setFirstResult(1); + // Lock all selected Employees, skip the first one, i.e should lock Employee(2) + query.setLockMode(LockModeType.PESSIMISTIC_READ); + query.setHint("javax.persistence.query.timeout", 2000); + List<Employee> q = query.getResultList(); + assertEquals("Expected 1 element with emplyee id=2", q.size(), 1); + assertTrue("Test Employee first name = 'first.2'", q.get(0).getFirstName().equals("first.1") + || q.get(0).getFirstName().equals("first.2")); + em2.getTransaction().begin(); + Map<String,Object> map = new HashMap<String,Object>(); + map.put("javax.persistence.lock.timeout", 2000); + // find Employee(2) with a lock, should block and expected a PessimisticLockException + em2.find(Employee.class, 2, LockModeType.PESSIMISTIC_READ, map); + fail("Unexcpected find succeeded. Should throw a PessimisticLockException."); + } catch (QueryTimeoutException e) { + // TODO: DB2: This is the current unexpected exception due to OPENJPA-991. + // Remove this when the problem is fixed +// System.out.println("Caught " + e.getClass().getName() + ":" + e.getMessage()); + } catch (PessimisticLockException e) { + // TODO: This is the expected exception but will be fixed under OPENJPA-991 +// System.out.println("Caught " + e.getClass().getName() + ":" + e.getMessage()); + } catch (Exception ex) { + fail("Caught unexpected " + ex.getClass().getName() + ":" + ex.getMessage()); + } finally { + if( em1.getTransaction().isActive()) + em1.getTransaction().rollback(); + if( em2.getTransaction().isActive()) + em2.getTransaction().rollback(); + } + + try { + em1.getTransaction().begin(); + Query query = em1.createQuery( + "select e.department from Employee e where e.id < 10").setFirstResult(1); + // Lock all selected Departments, skip the first one, i.e should lock Department(20) + query.setLockMode(LockModeType.PESSIMISTIC_READ); + query.setHint("javax.persistence.query.timeout", 2000); + List<Department> q = query.getResultList(); + assertEquals("Expected 1 element with department id=20", q.size(), 1); + assertTrue("Test department name = 'D20'", q.get(0).getName().equals("D10") + || q.get(0).getName().equals("D20")); + + em2.getTransaction().begin(); + Map<String,Object> map = new HashMap<String,Object>(); + map.put("javax.persistence.lock.timeout", 2000); + // find Employee(2) with a lock, no block since only department was locked + Employee emp = em2.find(Employee.class, 1, LockModeType.PESSIMISTIC_READ, map); + assertNotNull("Query locks department only, therefore should find Employee.", emp); + assertEquals("Test Employee first name = 'first.1'", emp.getFirstName(), "first.1"); + } catch (QueryTimeoutException e) { + // TODO: DB2: This is the current unexpected exception due to OPENJPA-991. + // Remove this when the problem is fixed +// System.out.println("Caught " + e.getClass().getName() + ":" + e.getMessage()); + if( !(dict instanceof org.apache.openjpa.jdbc.sql.DB2Dictionary)) { + fail("Caught unexpected " + e.getClass().getName() + ":" + e.getMessage()); + } + } catch (PessimisticLockException e) { + // TODO: This is the expected exception but will be fixed under OPENJPA-991 +// System.out.println("Caught " + e.getClass().getName() + ":" + e.getMessage()); + if( !(dict instanceof org.apache.openjpa.jdbc.sql.DB2Dictionary)) { + fail("Caught unexpected " + e.getClass().getName() + ":" + e.getMessage()); + } + } catch (Exception ex) { + fail("Caught unexpected " + ex.getClass().getName() + ":" + ex.getMessage()); + } finally { + if( em1.getTransaction().isActive()) + em1.getTransaction().rollback(); + if( em2.getTransaction().isActive()) + em2.getTransaction().rollback(); + } + em1.close(); + em2.close(); + } + + /* + * Test find with pessimistic lock after a query with pessimistic lock. + */ + public void testFindAfterQueryOrderByWithPessimisticLocks() { + EntityManager em1 = emf.createEntityManager(); + EntityManager em2 = emf.createEntityManager(); + try { + em1.getTransaction().begin(); Query query = em1.createQuery( "select e from Employee e where e.id < 10 order by e.id").setFirstResult(1); + // Lock all selected Employees, skip the first one, i.e should lock Employee(2) query.setLockMode(LockModeType.PESSIMISTIC_READ); + query.setHint("javax.persistence.query.timeout", 2000); List<Employee> q = query.getResultList(); assertEquals("Expected 1 element with emplyee id=2", q.size(), 1); assertEquals("Test Employee first name = 'first.2'", q.get(0).getFirstName(), "first.2"); em2.getTransaction().begin(); - Map<String,Object> map = new HashMap<String,Object>(); map.put("javax.persistence.lock.timeout", 2000); + // find Employee(2) with a lock, should block and expected a PessimisticLockException em2.find(Employee.class, 2, LockModeType.PESSIMISTIC_READ, map); fail("Unexcpected find succeeded. Should throw a PessimisticLockException."); } catch (QueryTimeoutException e) { @@ -135,27 +226,35 @@ try { em1.getTransaction().begin(); - Query query = em1.createQuery( "select e.department from Employee e where e.id < 10 order by e.department.id").setFirstResult(1); + // Lock all selected Departments, skip the first one, i.e should lock Department(20) query.setLockMode(LockModeType.PESSIMISTIC_READ); + query.setHint("javax.persistence.query.timeout", 2000); List<Department> q = query.getResultList(); assertEquals("Expected 1 element with department id=20", q.size(), 1); assertEquals("Test department name = 'D20'", q.get(0).getName(), "D20"); em2.getTransaction().begin(); - Map<String,Object> map = new HashMap<String,Object>(); map.put("javax.persistence.lock.timeout", 2000); + // find Employee(2) with a lock, no block since only department was locked Employee emp = em2.find(Employee.class, 1, LockModeType.PESSIMISTIC_READ, map); - assertNotNull("Query locks department but find locks Employee.", emp); - fail("Unexcpected find succeeded. Should throw a PessimisticLockException."); + assertNotNull("Query locks department only, therefore should find Employee.", emp); + assertEquals("Test Employee first name = 'first.1'", emp.getFirstName(), "first.1"); } catch (QueryTimeoutException e) { - // TODO: This is the current unexpected exception due to OPENJPA-991. Remove this when the problem is fixed -// System.out.println("Caught " + e.getClass().getName() + ":" + e.getMessage()); + // TODO: DB2: This is the current unexpected exception due to OPENJPA-991. + // Remove this when the problem is fixed +// System.out.println("Caught " + e.getClass().getName() + ":" + e.getMessage()); + if( !(dict instanceof org.apache.openjpa.jdbc.sql.DB2Dictionary)) { + fail("Caught unexpected " + e.getClass().getName() + ":" + e.getMessage()); + } } catch (PessimisticLockException e) { // TODO: This is the expected exception but will be fixed under OPENJPA-991 -// System.out.println("Caught " + e.getClass().getName() + ":" + e.getMessage()); +// System.out.println("Caught " + e.getClass().getName() + ":" + e.getMessage()); + if( !(dict instanceof org.apache.openjpa.jdbc.sql.DB2Dictionary)) { + fail("Caught unexpected " + e.getClass().getName() + ":" + e.getMessage()); + } } catch (Exception ex) { fail("Caught unexpected " + ex.getClass().getName() + ":" + ex.getMessage()); } finally { @@ -169,28 +268,41 @@ } /* - * Test a query with pessimistic lock after a find with pessimistic lock and expect PessimisticLockException. + * Test query with pessimistic lock after a find with pessimistic lock. */ public void testQueryAfterFindWithPessimisticLocks() { EntityManager em1 = emf.createEntityManager(); EntityManager em2 = emf.createEntityManager(); try { em2.getTransaction().begin(); - Map<String,Object> map = new HashMap<String,Object>(); map.put("javax.persistence.lock.timeout", 2000); + // Lock Emplyee(1), no department should be locked em2.find(Employee.class, 1, LockModeType.PESSIMISTIC_READ, map); em1.getTransaction().begin(); - Query query = em1.createQuery( - "select e.department from Employee e where e.id < 10 order by e.department.id").setFirstResult(1); + "select e.department from Employee e where e.id < 10").setFirstResult(1); query.setLockMode(LockModeType.PESSIMISTIC_READ); + query.setHint("javax.persistence.query.timeout", 2000); + // Lock all selected Department but skip the first, i.e. lock Department(20), should query successfully. List<Department> q = query.getResultList(); - - fail("Unexcpected find succeeded. Should throw a PessimisticLockException."); + assertEquals("Expected 1 element with department id=20", q.size(), 1); + assertTrue("Test department name = 'D20'", q.get(0).getName().equals("D10") + || q.get(0).getName().equals("D20")); + } catch (QueryTimeoutException e) { + // TODO: DB2: This is the current unexpected exception due to OPENJPA-991. + // Remove this when the problem is fixed +// System.out.println("Caught " + e.getClass().getName() + ":" + e.getMessage()); + if( !(dict instanceof org.apache.openjpa.jdbc.sql.DB2Dictionary)) { + fail("Caught unexpected " + e.getClass().getName() + ":" + e.getMessage()); + } } catch (PessimisticLockException e) { - // This is the expected exception. + // TODO: This is the expected exception but will be fixed under OPENJPA-991 +// System.out.println("Caught " + e.getClass().getName() + ":" + e.getMessage()); + if( !(dict instanceof org.apache.openjpa.jdbc.sql.DB2Dictionary)) { + fail("Caught unexpected " + e.getClass().getName() + ":" + e.getMessage()); + } } catch (Exception ex) { fail("Caught unexpected " + ex.getClass().getName() + ":" + ex.getMessage()); } finally { @@ -199,35 +311,107 @@ if (em2.getTransaction().isActive()) em2.getTransaction().rollback(); } + + try { + em2.getTransaction().begin(); + + Map<String,Object> map = new HashMap<String,Object>(); + map.put("javax.persistence.lock.timeout", 2000); + // Lock Emplyee(2), no department should be locked + em2.find(Employee.class, 2, LockModeType.PESSIMISTIC_READ, map); + + em1.getTransaction().begin(); + Query query = em1.createQuery( + "select e from Employee e where e.id < 10").setFirstResult(1); + // Lock all selected Employees, skip the first one, i.e should lock Employee(2) + query.setLockMode(LockModeType.PESSIMISTIC_READ); + query.setHint("javax.persistence.query.timeout", 2000); + List<Employee> q = query.getResultList(); + fail("Unexcpected find succeeded. Should throw a QueryLockException."); + } catch (QueryTimeoutException e) { + // This is the expected exception. +// System.out.println("Caught " + e.getClass().getName() + ":" + e.getMessage()); + } catch (PessimisticLockException e) { + // TODO: This is the expected exception but will be fixed under OPENJPA-991 +// System.out.println("Caught " + e.getClass().getName() + ":" + e.getMessage()); + } catch (Exception ex) { + fail("Caught unexpected " + ex.getClass().getName() + ":" + ex.getMessage()); + } finally { + if( em1.getTransaction().isActive()) + em1.getTransaction().rollback(); + if( em2.getTransaction().isActive()) + em2.getTransaction().rollback(); + } em1.close(); em2.close(); } /* - * Test a query with pessimistic lock with query timeout set after a find - * with pessimistic lock and expect QueryTimeoutException. + * Test query with pessimistic lock after a find with pessimistic lock. */ - public void testQueryWithQueryTimeoutAfterFindWithPessimisticLocks() { + public void testQueryOrderByAfterFindWithPessimisticLocks() { EntityManager em1 = emf.createEntityManager(); EntityManager em2 = emf.createEntityManager(); try { em2.getTransaction().begin(); - Map<String,Object> map = new HashMap<String,Object>(); map.put("javax.persistence.lock.timeout", 2000); + // Lock Emplyee(1), no department should be locked em2.find(Employee.class, 1, LockModeType.PESSIMISTIC_READ, map); em1.getTransaction().begin(); - Query query = em1.createQuery( "select e.department from Employee e where e.id < 10 order by e.department.id").setFirstResult(1); query.setLockMode(LockModeType.PESSIMISTIC_READ); query.setHint("javax.persistence.query.timeout", 2000); + // Lock all selected Department but skip the first, i.e. lock Department(20), should query successfully. List<Department> q = query.getResultList(); + assertEquals("Expected 1 element with department id=20", q.size(), 1); + assertEquals("Test department name = 'D20'", q.get(0).getName(), "D20"); + } catch (QueryTimeoutException e) { + // TODO: DB2: This is the current unexpected exception due to OPENJPA-991. + // Remove this when the problem is fixed +// System.out.println("Caught " + e.getClass().getName() + ":" + e.getMessage()); + if( !(dict instanceof org.apache.openjpa.jdbc.sql.DB2Dictionary)) { + fail("Caught unexpected " + e.getClass().getName() + ":" + e.getMessage()); + } + } catch (PessimisticLockException e) { + // TODO: This is the expected exception but will be fixed under OPENJPA-991 +// System.out.println("Caught " + e.getClass().getName() + ":" + e.getMessage()); + if( !(dict instanceof org.apache.openjpa.jdbc.sql.DB2Dictionary)) { + fail("Caught unexpected " + e.getClass().getName() + ":" + e.getMessage()); + } + } catch (Exception ex) { + fail("Caught unexpected " + ex.getClass().getName() + ":" + ex.getMessage()); + } finally { + if( em1.getTransaction().isActive()) + em1.getTransaction().rollback(); + if (em2.getTransaction().isActive()) + em2.getTransaction().rollback(); + } + + try { + em2.getTransaction().begin(); - fail("Unexcpected find succeeded. Should throw a PessimisticLockException."); + Map<String,Object> map = new HashMap<String,Object>(); + map.put("javax.persistence.lock.timeout", 2000); + // Lock Emplyee(2), no department should be locked + em2.find(Employee.class, 2, LockModeType.PESSIMISTIC_READ, map); + + em1.getTransaction().begin(); + Query query = em1.createQuery( + "select e from Employee e where e.id < 10 order by e.department.id").setFirstResult(1); + // Lock all selected Employees, skip the first one, i.e should lock Employee(2) + query.setLockMode(LockModeType.PESSIMISTIC_READ); + query.setHint("javax.persistence.query.timeout", 2000); + List<Employee> q = query.getResultList(); + fail("Unexcpected find succeeded. Should throw a QueryLockException."); } catch (QueryTimeoutException e) { // This is the expected exception. +// System.out.println("Caught " + e.getClass().getName() + ":" + e.getMessage()); + } catch (PessimisticLockException e) { + // TODO: This is the expected exception but will be fixed under OPENJPA-991 +// System.out.println("Caught " + e.getClass().getName() + ":" + e.getMessage()); } catch (Exception ex) { fail("Caught unexpected " + ex.getClass().getName() + ":" + ex.getMessage()); } finally {
