mirror of https://github.com/apache/openjpa.git
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:
parent
6cb121e192
commit
4611bf9e43
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -172,6 +172,10 @@ public class NativeJDBCSeq
|
|||
schema.importSequence(_seq);
|
||||
}
|
||||
|
||||
public JDBCConfiguration getConfiguration() {
|
||||
return _conf;
|
||||
}
|
||||
|
||||
public void setConfiguration(Configuration conf) {
|
||||
_conf = (JDBCConfiguration) conf;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue