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.Connection;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
import javax.transaction.Transaction;
|
||||||
|
import javax.transaction.TransactionManager;
|
||||||
|
|
||||||
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
|
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
|
||||||
import org.apache.openjpa.jdbc.meta.ClassMapping;
|
import org.apache.openjpa.jdbc.meta.ClassMapping;
|
||||||
|
@ -40,6 +42,7 @@ public abstract class AbstractJDBCSeq
|
||||||
|
|
||||||
protected int type = TYPE_DEFAULT;
|
protected int type = TYPE_DEFAULT;
|
||||||
protected Object current = null;
|
protected Object current = null;
|
||||||
|
private transient Transaction _outerTransaction;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Records the sequence type.
|
* Records the sequence type.
|
||||||
|
@ -107,6 +110,11 @@ public abstract class AbstractJDBCSeq
|
||||||
ClassMapping mapping)
|
ClassMapping mapping)
|
||||||
throws Exception;
|
throws Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the {@link JDBCConfiguration} for this sequence.
|
||||||
|
*/
|
||||||
|
public abstract JDBCConfiguration getConfiguration();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the current sequence object. By default returns the last
|
* Return the current sequence object. By default returns the last
|
||||||
* sequence value used, or null if no sequence values have been requested
|
* sequence value used, or null if no sequence values have been requested
|
||||||
|
@ -140,7 +148,17 @@ public abstract class AbstractJDBCSeq
|
||||||
throws SQLException {
|
throws SQLException {
|
||||||
if (type == TYPE_TRANSACTIONAL || type == TYPE_CONTIGUOUS)
|
if (type == TYPE_TRANSACTIONAL || type == TYPE_CONTIGUOUS)
|
||||||
return store.getConnection();
|
return store.getConnection();
|
||||||
|
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();
|
JDBCConfiguration conf = store.getConfiguration();
|
||||||
DataSource ds = conf.getDataSource2(store.getContext());
|
DataSource ds = conf.getDataSource2(store.getContext());
|
||||||
Connection conn = ds.getConnection();
|
Connection conn = ds.getConnection();
|
||||||
|
@ -148,6 +166,7 @@ public abstract class AbstractJDBCSeq
|
||||||
conn.setAutoCommit(false);
|
conn.setAutoCommit(false);
|
||||||
return conn;
|
return conn;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Close the current connection.
|
* Close the current connection.
|
||||||
|
@ -156,8 +175,26 @@ public abstract class AbstractJDBCSeq
|
||||||
if (conn == null)
|
if (conn == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
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 {
|
try {
|
||||||
if (type != TYPE_TRANSACTIONAL && type != TYPE_CONTIGUOUS)
|
|
||||||
conn.commit();
|
conn.commit();
|
||||||
} catch (SQLException se) {
|
} catch (SQLException se) {
|
||||||
throw SQLExceptions.getStore(se);
|
throw SQLExceptions.getStore(se);
|
||||||
|
@ -165,4 +202,14 @@ public abstract class AbstractJDBCSeq
|
||||||
try { conn.close(); } catch (SQLException se) {}
|
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);
|
schema.importSequence(_seq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public JDBCConfiguration getConfiguration() {
|
||||||
|
return _conf;
|
||||||
|
}
|
||||||
|
|
||||||
public void setConfiguration(Configuration conf) {
|
public void setConfiguration(Configuration conf) {
|
||||||
_conf = (JDBCConfiguration) conf;
|
_conf = (JDBCConfiguration) conf;
|
||||||
}
|
}
|
||||||
|
|
|
@ -331,6 +331,7 @@ public class TableJDBCSeq
|
||||||
// possible that we might get errors when inserting if
|
// possible that we might get errors when inserting if
|
||||||
// another thread/process is inserting same pk at same time
|
// 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();
|
conn = _conf.getDataSource2(store.getContext()).getConnection();
|
||||||
try {
|
try {
|
||||||
insertSequence(mapping, conn);
|
insertSequence(mapping, conn);
|
||||||
|
@ -377,7 +378,7 @@ public class TableJDBCSeq
|
||||||
appendValue(Numbers.valueOf(1), _seqColumn).append(")");
|
appendValue(Numbers.valueOf(1), _seqColumn).append(")");
|
||||||
|
|
||||||
boolean wasAuto = conn.getAutoCommit();
|
boolean wasAuto = conn.getAutoCommit();
|
||||||
if (!wasAuto)
|
if (!wasAuto && !suspendInJTA())
|
||||||
conn.setAutoCommit(true);
|
conn.setAutoCommit(true);
|
||||||
|
|
||||||
PreparedStatement stmnt = null;
|
PreparedStatement stmnt = null;
|
||||||
|
@ -387,7 +388,7 @@ public class TableJDBCSeq
|
||||||
} finally {
|
} finally {
|
||||||
if (stmnt != null)
|
if (stmnt != null)
|
||||||
try { stmnt.close(); } catch (SQLException se) {}
|
try { stmnt.close(); } catch (SQLException se) {}
|
||||||
if (!wasAuto)
|
if (!wasAuto && !suspendInJTA())
|
||||||
conn.setAutoCommit(false);
|
conn.setAutoCommit(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue