diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PessimisticLockManager.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PessimisticLockManager.java index f81c93af5..bbb50dafb 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PessimisticLockManager.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PessimisticLockManager.java @@ -86,7 +86,7 @@ public class PessimisticLockManager setLockLevel(sm, LOCK_DATASTORE_ONLY); } - protected void lockInternal(OpenJPAStateManager sm, int level, long timeout, + protected void lockInternal(OpenJPAStateManager sm, int level, int timeout, Object sdata) { // we can skip any already-locked instance regardless of level because // we treat all locks the same (though super doesn't) @@ -103,7 +103,7 @@ public class PessimisticLockManager * Lock the specified instance row by issuing a "SELECT ... FOR UPDATE" * statement. */ - private void lockRow(OpenJPAStateManager sm, long timeout) { + private void lockRow(OpenJPAStateManager sm, int timeout) { // assert that the dictionary supports the "SELECT ... FOR UPDATE" // construct; if not, and we the assertion does not throw an // exception, then just return without locking @@ -136,7 +136,7 @@ public class PessimisticLockManager if (log.isWarnEnabled()) log.warn(_loc.get("millis-query-timeout")); } - stmnt.setQueryTimeout((int) (timeout / 1000)); + stmnt.setQueryTimeout(timeout / 1000); } rs = stmnt.executeQuery(); if (!rs.next()) @@ -145,19 +145,10 @@ public class PessimisticLockManager throw SQLExceptions.getStore(se, dict); } finally { if (stmnt != null) - try { - stmnt.close(); - } catch (SQLException se) { - } + try { stmnt.close(); } catch (SQLException se) {} if (rs != null) - try { - rs.close(); - } catch (SQLException se) { - } - try { - conn.close(); - } catch (SQLException se) { - } + try { rs.close(); } catch (SQLException se) {} + try { conn.close(); } catch (SQLException se) {} } } diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java index de3293000..7727b6e64 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java @@ -340,8 +340,19 @@ public class SelectImpl else stmnt = sql.prepareStatement(conn, rsType, -1); - if (forUpdate) + // if this is a locking select and the lock timeout is greater than + // the configured query timeout, use the lock timeout + if (forUpdate && _dict.supportsQueryTimeout && fetch != null + && fetch.getLockTimeout() > stmnt.getQueryTimeout() * 1000) { + int timeout = fetch.getLockTimeout(); + if (timeout < 1000) { + timeout = 1000; + Log log = _conf.getLog(JDBCConfiguration.LOG_JDBC); + if (log.isWarnEnabled()) + log.warn(_loc.get("millis-query-timeout")); + } stmnt.setQueryTimeout(fetch.getLockTimeout() / 1000); + } rs = stmnt.executeQuery(); } catch (SQLException se) { // clean up statement diff --git a/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/kernel/localizer.properties b/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/kernel/localizer.properties index 18b5bffb9..b0a3a5c60 100644 --- a/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/kernel/localizer.properties +++ b/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/kernel/localizer.properties @@ -48,11 +48,8 @@ cant-lock-on-load: The database is unable to lock this query. Each object \ start-trans-for-lock: Though you are using optimistic transactions, OpenJPA is \ now beginning a datastore transaction because you have requested a lock \ on some data. -millis-timeout: JDBC lock manager does not support millisecond-granularity \ - timeouts. Use timeouts that are multiples of 1000 for even second values. -millis-query-timeout: JDBC lock manager does not support \ - millisecond-granularity timeouts. Use timeouts that are multiples \ - of 1000 for even second values. +millis-query-timeout: JDBC locking does not support millisecond-granularity \ + timeouts. Use timeouts that are multiples of 1000 for even second values. batch-not-supported: The update count for the statement was an invalid \ value ({0}). This indicates that your database or JDBC driver does not \ have complete support for executing batch statements. Batch \ @@ -101,4 +98,4 @@ bad-level: Invalid isolation level. Valid levels are -1, \ Connection.TRANSACTION_NONE, Connection.TRANSACTION_READ_UNCOMMITTED, \ Connection.TRANSACTION_READ_COMMITTED, \ Connection.TRANSACTION_REPEATABLE_READ, or \ - Connection.TRANSACTION_SERIALIZABLE. Specified value: {0}. \ No newline at end of file + Connection.TRANSACTION_SERIALIZABLE. Specified value: {0}. diff --git a/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/sql/localizer.properties b/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/sql/localizer.properties index fe43ecd36..683ff7651 100644 --- a/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/sql/localizer.properties +++ b/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/sql/localizer.properties @@ -161,4 +161,6 @@ oracle-timestamp-bug: An ArrayIndexOutOfBoundsException has occured when \ worked around by setting the "SupportsTimestampNanos" DBDictionary \ property to "true". isolation-level-config-not-supported: This DBDictionary does not support \ - customization of isolation levels on a per-query basis. DBDictionary: {0}. \ No newline at end of file + customization of isolation levels on a per-query basis. DBDictionary: {0}. +millis-query-timeout: JDBC locking does not support millisecond-granularity \ + timeouts. Use timeouts that are multiples of 1000 for even second values. diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/VersionLockManager.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/VersionLockManager.java index ee39e982e..36c1f60fd 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/VersionLockManager.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/VersionLockManager.java @@ -90,7 +90,7 @@ public class VersionLockManager * * @see StoreContext#transactional */ - protected void lockInternal(OpenJPAStateManager sm, int level, long timeout, + protected void lockInternal(OpenJPAStateManager sm, int level, int timeout, Object sdata) { // Set lock level first to prevent infinite recursion with // transactional(..) call