Code changes for OPENJPA-93: sequence maintainance in JTA env without non-JTA datasource. This has been nominally tested in WebLogic Server.

git-svn-id: https://svn.apache.org/repos/asf/incubator/openjpa/trunk@491147 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Patrick Linskey 2006-12-30 01:20:55 +00:00
parent 6cb121e192
commit 4611bf9e43
3 changed files with 68 additions and 16 deletions

View File

@ -18,6 +18,8 @@ package org.apache.openjpa.jdbc.kernel;
import java.sql.Connection;
import java.sql.SQLException;
import javax.sql.DataSource;
import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
import org.apache.openjpa.jdbc.meta.ClassMapping;
@ -40,6 +42,7 @@ public abstract class AbstractJDBCSeq
protected int type = TYPE_DEFAULT;
protected Object current = null;
private transient Transaction _outerTransaction;
/**
* Records the sequence type.
@ -106,6 +109,11 @@ public abstract class AbstractJDBCSeq
protected abstract Object nextInternal(JDBCStore store,
ClassMapping mapping)
throws Exception;
/**
* Return the {@link JDBCConfiguration} for this sequence.
*/
public abstract JDBCConfiguration getConfiguration();
/**
* Return the current sequence object. By default returns the last
@ -140,13 +148,24 @@ public abstract class AbstractJDBCSeq
throws SQLException {
if (type == TYPE_TRANSACTIONAL || type == TYPE_CONTIGUOUS)
return store.getConnection();
JDBCConfiguration conf = store.getConfiguration();
DataSource ds = conf.getDataSource2(store.getContext());
Connection conn = ds.getConnection();
if (conn.getAutoCommit())
conn.setAutoCommit(false);
return conn;
else if (suspendInJTA()) {
try {
TransactionManager tm = getConfiguration()
.getManagedRuntimeInstance().getTransactionManager();
_outerTransaction = tm.suspend();
tm.begin();
return store.getConnection();
} catch (Exception e) {
throw new StoreException(e);
}
} else {
JDBCConfiguration conf = store.getConfiguration();
DataSource ds = conf.getDataSource2(store.getContext());
Connection conn = ds.getConnection();
if (conn.getAutoCommit())
conn.setAutoCommit(false);
return conn;
}
}
/**
@ -156,13 +175,41 @@ public abstract class AbstractJDBCSeq
if (conn == null)
return;
try {
if (type != TYPE_TRANSACTIONAL && type != TYPE_CONTIGUOUS)
if (type == TYPE_TRANSACTIONAL || type == TYPE_CONTIGUOUS) {
// do nothing; this seq is part of the business transaction
return;
} else if (suspendInJTA()) {
try {
TransactionManager tm = getConfiguration()
.getManagedRuntimeInstance().getTransactionManager();
tm.commit();
try { conn.close(); } catch (SQLException se) {}
if (_outerTransaction != null)
tm.resume(_outerTransaction);
} catch (Exception e) {
throw new StoreException(e);
} finally {
_outerTransaction = null;
}
} else {
try {
conn.commit();
} catch (SQLException se) {
throw SQLExceptions.getStore(se);
} finally {
try { conn.close(); } catch (SQLException se) {}
} catch (SQLException se) {
throw SQLExceptions.getStore(se);
} finally {
try { conn.close(); } catch (SQLException se) {}
}
}
}
/**
* Detect whether or not OpenJPA should suspend the transaction in
* a managed environment.
*/
protected boolean suspendInJTA() {
return getConfiguration().isConnectionFactoryModeManaged() &&
getConfiguration().getConnectionFactory2() == null;
}
}

View File

@ -172,6 +172,10 @@ public class NativeJDBCSeq
schema.importSequence(_seq);
}
public JDBCConfiguration getConfiguration() {
return _conf;
}
public void setConfiguration(Configuration conf) {
_conf = (JDBCConfiguration) conf;
}

View File

@ -330,7 +330,8 @@ public class TableJDBCSeq
try {
// possible that we might get errors when inserting if
// another thread/process is inserting same pk at same time
SQLException err = null;
SQLException err = null;
// ### why does this not call getConnection() / closeConnection()?
conn = _conf.getDataSource2(store.getContext()).getConnection();
try {
insertSequence(mapping, conn);
@ -377,7 +378,7 @@ public class TableJDBCSeq
appendValue(Numbers.valueOf(1), _seqColumn).append(")");
boolean wasAuto = conn.getAutoCommit();
if (!wasAuto)
if (!wasAuto && !suspendInJTA())
conn.setAutoCommit(true);
PreparedStatement stmnt = null;
@ -387,7 +388,7 @@ public class TableJDBCSeq
} finally {
if (stmnt != null)
try { stmnt.close(); } catch (SQLException se) {}
if (!wasAuto)
if (!wasAuto && !suspendInJTA())
conn.setAutoCommit(false);
}
}