--- openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCFetchConfiguration.java (revision 525577)
+++ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCFetchConfiguration.java Wed Apr 04 15:54:04 PDT 2007
@@ -16,6 +16,7 @@
package org.apache.openjpa.jdbc.kernel;
import java.sql.ResultSet;
+import java.sql.Connection;
import java.util.Collection;
import java.util.Set;
@@ -169,4 +170,38 @@
* Convenience method to cast traversal to store-specific type.
*/
public JDBCFetchConfiguration traverseJDBC(FieldMetaData fm);
+
+ /**
+ *
The isolation level for queries issued to the database. This overrides
+ * the persistence-unit-wide openjpa.jdbc.TransactionIsolation
+ * value.
+ *
+ * Must be one of {@link Connection#TRANSACTION_NONE},
+ * {@link Connection#TRANSACTION_READ_UNCOMMITTED},
+ * {@link Connection#TRANSACTION_READ_COMMITTED},
+ * {@link Connection#TRANSACTION_REPEATABLE_READ},
+ * {@link Connection#TRANSACTION_SERIALIZABLE},
+ * or -1 for the default connection level specified by the context in
+ * which this fetch configuration is being used.
+ *
+ * @since 0.9.7
+ */
+ public int getIsolationLevel();
+
+ /**
+ * The isolation level for queries issued to the database. This overrides
+ * the persistence-unit-wide openjpa.jdbc.TransactionIsolation
+ * value.
+ *
+ * Must be one of {@link Connection#TRANSACTION_NONE},
+ * {@link Connection#TRANSACTION_READ_UNCOMMITTED},
+ * {@link Connection#TRANSACTION_READ_COMMITTED},
+ * {@link Connection#TRANSACTION_REPEATABLE_READ},
+ * {@link Connection#TRANSACTION_SERIALIZABLE},
+ * or -1 for the default connection level specified by the context in
+ * which this fetch configuration is being used.
+ *
+ * @since 0.9.7
+ */
+ public JDBCFetchConfiguration setIsolationLevel(int level);
}
--- openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/DelegatingJDBCFetchConfiguration.java (revision 525577)
+++ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/DelegatingJDBCFetchConfiguration.java Wed Apr 04 15:38:01 PDT 2007
@@ -240,4 +240,21 @@
throw translate(re);
}
}
+
+ public int getIsolationLevel() {
+ try {
+ return getJDBCDelegate().getIsolationLevel();
+ } catch (RuntimeException re) {
+ throw translate(re);
-}
+ }
+ }
+
+ public JDBCFetchConfiguration setIsolationLevel(int level) {
+ try {
+ getJDBCDelegate().setIsolationLevel(level);
+ return this;
+ } catch (RuntimeException re) {
+ throw translate(re);
+ }
+ }
+}
--- openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/kernel/localizer.properties (revision 525577)
+++ openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/kernel/localizer.properties Wed Apr 04 16:03:51 PDT 2007
@@ -97,3 +97,8 @@
native-seq-usage: Usage: java org.apache.openjpa.jdbc.kernel.NativeJDBCSeq\n\
\t[-properties/-p ]\n\
\t[- ]*
+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
--- openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java (revision 525583)
+++ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java Wed Apr 04 16:30:21 PDT 2007
@@ -23,8 +23,8 @@
import java.util.StringTokenizer;
import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
import org.apache.openjpa.jdbc.schema.Sequence;
-import org.apache.openjpa.lib.log.Log;
import org.apache.openjpa.util.OpenJPAException;
+import org.apache.openjpa.kernel.LockLevels;
/**
* Dictionary for IBM DB2 database.
@@ -35,19 +35,20 @@
public String optimizeClause = "optimize for";
public String rowClause = "row";
private int db2ServerType = 0;
- private static final int db2ISeriesV5R3AndEarlier = 1;
+ private static final int db2ISeriesV5R3AndEarlier = 1;
private static final int db2UDBV81OrEarlier = 2;
private static final int db2ZOSV8x = 3;
private static final int db2UDBV82AndLater = 4;
- private static final int db2ISeriesV5R4AndLater = 5;
+ private static final int db2ISeriesV5R4AndLater = 5;
- private static final String forUpdateOfClause="FOR UPDATE OF";
+ private static final String forUpdateOfClause = "FOR UPDATE OF";
- private static final String withRSClause="WITH RS";
+ private static final String withRSClause = "WITH RS";
- private static final String withRRClause="WITH RR";
+ private static final String withRRClause = "WITH RR";
- private static final String useKeepUpdateLockClause= "USE AND KEEP UPDATE LOCKS";
- private static final String useKeepExclusiveLockClause="USE AND KEEP EXCLUSIVE LOCKS";
+ private static final String useKeepUpdateLockClause
+ = "USE AND KEEP UPDATE LOCKS";
+ private static final String useKeepExclusiveLockClause
+ = "USE AND KEEP EXCLUSIVE LOCKS";
- private static final String forReadOnlyClause = "FOR READ ONLY";
+ private static final String forReadOnlyClause = "FOR READ ONLY";
- public static final String UPDATE_HINT = "openjpa.hint.updateClause";
- public static final String ISOLATION_HINT = "openjpa.hint.isolationLevel";
+
public DB2Dictionary() {
platform = "DB2";
validationSQL = "SELECT DISTINCT(CURRENT TIMESTAMP) FROM "
@@ -229,26 +230,28 @@
/** Get the update clause for the query based on the
* updateClause and isolationLevel hints
*/
- public String getForUpdateClause(JDBCFetchConfiguration fetch, boolean forUpdate) {
- String isolationLevel = null;
+ public String getForUpdateClause(JDBCFetchConfiguration fetch,
+ boolean forUpdate) {
+ int isolationLevel;
boolean updateClause;
- DatabaseMetaData metaData = null;
StringBuffer forUpdateString = new StringBuffer();
try {
- // Determine the update clause/isolationLevel the hint
- // overrides the persistence.xml value
- if (fetch != null && fetch.getHint(UPDATE_HINT)
- !=null )
- updateClause = ((Boolean)fetch.
- getHint(UPDATE_HINT)).booleanValue();
+ // Determine the update clause/isolationLevel; the fetch
+ // configuration data overrides the persistence.xml value
+ if (fetch != null
+ && fetch.getReadLockLevel() == LockLevels.LOCK_WRITE)
+ updateClause = true;
+ else if (fetch != null
+ && fetch.getReadLockLevel() == LockLevels.LOCK_READ)
+ updateClause = false;
- else
+ else
updateClause = forUpdate;
- if (fetch != null &&fetch.getHint(ISOLATION_HINT)
- !=null )
- isolationLevel = (String)fetch.
- getHint(ISOLATION_HINT);
+
+ if (fetch != null && fetch.getIsolationLevel() != -1)
+ isolationLevel = fetch.getIsolationLevel();
- else
+ else
- isolationLevel = conf.getTransactionIsolation();
+ isolationLevel = conf.getTransactionIsolationConstant();
+
if (updateClause == false)
// This sql is not for update so add FOR Read Only clause
forUpdateString.append(" ").append(forReadOnlyClause)
@@ -258,36 +261,41 @@
switch(db2ServerType){
case db2ISeriesV5R3AndEarlier:
case db2UDBV81OrEarlier:
- if (isolationLevel.equals("read-uncommitted"))
+ if (isolationLevel ==
+ Connection.TRANSACTION_READ_UNCOMMITTED) {
forUpdateString.append(" ").append(withRSClause)
- .append(" ").append(forUpdateOfClause).append(" ");
+ .append(" ").append(forUpdateOfClause).append(" ");
- else
+ } else {
forUpdateString.append(" ").append(forUpdateOfClause)
- .append(" ");
+ .append(" ");
+ }
- break;
+ break;
case db2ZOSV8x:
case db2UDBV82AndLater:
- if (isolationLevel.equals("serializable"))
+ if (isolationLevel == Connection.TRANSACTION_SERIALIZABLE) {
forUpdateString.append(" ").append(withRRClause)
- .append(" ").append(useKeepUpdateLockClause)
- .append(" ");
+ .append(" ").append(useKeepUpdateLockClause)
+ .append(" ");
- else
+ } else {
forUpdateString.append(" ").append(withRSClause)
- .append(" ").append(useKeepUpdateLockClause)
- .append(" ");
+ .append(" ").append(useKeepUpdateLockClause)
+ .append(" ");
+ }
break;
case db2ISeriesV5R4AndLater:
- if (isolationLevel.equals("serializable"))
+ if (isolationLevel == Connection.TRANSACTION_SERIALIZABLE) {
forUpdateString.append(" ").append(withRRClause)
- .append(" ").append(useKeepExclusiveLockClause)
- .append(" ");
+ .append(" ").append(useKeepExclusiveLockClause)
+ .append(" ");
- else
+ } else {
forUpdateString.append(" ").append(withRSClause)
- .append(" ").append(useKeepExclusiveLockClause)
- .append(" ");
- }
+ .append(" ").append(useKeepExclusiveLockClause)
+ .append(" ");
+ }
+ break;
- }
- }
+ }
+ }
+ }
catch (Exception e) {
if (log.isTraceEnabled())
log.error(e.toString(),e);
--- openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/JDBCFetchPlanImpl.java (revision 525577)
+++ openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/JDBCFetchPlanImpl.java Wed Apr 04 15:36:26 PDT 2007
@@ -102,4 +102,13 @@
_fetch.setJoinSyntax(syntax);
return this;
}
+
+ public int getIsolationLevel() {
+ return _fetch.getIsolationLevel();
-}
+ }
+
+ public JDBCFetchPlan setIsolationLevel(int level) {
+ _fetch.setIsolationLevel(level);
+ return this;
+ }
+}
--- openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/JDBCFetchPlan.java (revision 525577)
+++ openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/JDBCFetchPlan.java Wed Apr 04 15:54:14 PDT 2007
@@ -15,6 +15,8 @@
*/
package org.apache.openjpa.persistence.jdbc;
+import java.sql.Connection;
+
import org.apache.openjpa.jdbc.kernel.EagerFetchModes;
import org.apache.openjpa.jdbc.kernel.LRSSizes;
import org.apache.openjpa.jdbc.sql.JoinSyntaxes;
@@ -114,4 +116,38 @@
* @see JoinSyntaxes
*/
public JDBCFetchPlan setJoinSyntax(int syntax);
+
+ /**
+ * The isolation level for queries issued to the database. This overrides
+ * the persistence-unit-wide openjpa.jdbc.TransactionIsolation
+ * value.
+ *
+ * Must be one of {@link Connection#TRANSACTION_NONE},
+ * {@link Connection#TRANSACTION_READ_UNCOMMITTED},
+ * {@link Connection#TRANSACTION_READ_COMMITTED},
+ * {@link Connection#TRANSACTION_REPEATABLE_READ},
+ * {@link Connection#TRANSACTION_SERIALIZABLE},
+ * or -1 for the default connection level specified by the context in
+ * which this fetch plan is being used.
+ *
+ * @since 0.9.7
+ */
+ public int getIsolationLevel();
+
+ /**
+ * The isolation level for queries issued to the database. This overrides
+ * the persistence-unit-wide openjpa.jdbc.TransactionIsolation
+ * value.
+ *
+ * Must be one of {@link Connection#TRANSACTION_NONE},
+ * {@link Connection#TRANSACTION_READ_UNCOMMITTED},
+ * {@link Connection#TRANSACTION_READ_COMMITTED},
+ * {@link Connection#TRANSACTION_REPEATABLE_READ},
+ * {@link Connection#TRANSACTION_SERIALIZABLE},
+ * or -1 for the default connection level specified by the context in
+ * which this fetch plan is being used.
+ *
+ * @since 0.9.7
+ */
+ public JDBCFetchPlan setIsolationLevel(int level);
}
--- openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCFetchConfigurationImpl.java (revision 525577)
+++ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCFetchConfigurationImpl.java Wed Apr 04 15:56:56 PDT 2007
@@ -17,6 +17,7 @@
import java.io.Serializable;
import java.sql.ResultSet;
+import java.sql.Connection;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
@@ -65,6 +66,7 @@
public int size = 0;
public int syntax = 0;
public Set joins = null;
+ public int isolationLevel = -1;
}
private final JDBCConfigurationState _state;
@@ -319,4 +321,22 @@
return null;
return (JDBCConfiguration) conf;
}
+
+ public int getIsolationLevel() {
+ return _state.isolationLevel;
-}
+ }
+
+ public JDBCFetchConfiguration setIsolationLevel(int level) {
+ if (level != -1
+ && level != Connection.TRANSACTION_NONE
+ && level != Connection.TRANSACTION_READ_UNCOMMITTED
+ && level != Connection.TRANSACTION_READ_COMMITTED
+ && level != Connection.TRANSACTION_REPEATABLE_READ
+ && level != Connection.TRANSACTION_SERIALIZABLE)
+ throw new IllegalArgumentException(
+ _loc.get("bad-level", Integer.valueOf(level)).getMessage());
+
+ _state.isolationLevel = level;
+ return this;
+ }
+}