| Method from org.jboss.resource.adapter.jdbc.BaseWrapperManagedConnection Detail: |
public void addConnectionEventListener(ConnectionEventListener cel) {
synchronized (cels)
{
cels.add(cel);
}
}
|
public void associateConnection(Object handle) throws ResourceException {
if (!(handle instanceof WrappedConnection))
throw new JBossResourceException("Wrong kind of connection handle to associate" + handle);
((WrappedConnection) handle).setManagedConnection(this);
synchronized (handles)
{
handles.add(handle);
}
}
|
protected void broadcastConnectionError(Throwable e) {
synchronized (stateLock)
{
if (destroyed)
{
Logger log = getLog();
if (log.isTraceEnabled())
log.trace("Not broadcasting error, already destroyed " + this, e);
return;
}
}
Exception ex = null;
if (e instanceof Exception)
ex = (Exception) e;
else
ex = new ResourceAdapterInternalException("Unexpected error", e);
ConnectionEvent ce = new ConnectionEvent(this, ConnectionEvent.CONNECTION_ERROR_OCCURRED, ex);
Collection copy = null;
synchronized (cels)
{
copy = new ArrayList(cels);
}
for (Iterator i = copy.iterator(); i.hasNext();)
{
ConnectionEventListener cel = (ConnectionEventListener) i.next();
try
{
cel.connectionErrorOccurred(ce);
}
catch (Throwable t)
{
getLog().warn("Error notifying of connection error for listener: " + cel, t);
}
}
}
|
boolean canUse(CachedPreparedStatement cachedps) {
// Nobody is using it so we are ok
if (cachedps.isInUse() == false)
return true;
// Cannot reuse prepared statements in auto commit mode
// if will close the previous usage of the PS
if (underlyingAutoCommit == true)
return false;
// We have been told not to share
return mcf.sharePS;
}
|
protected void checkException(SQLException e) throws ResourceException {
connectionError(e);
throw new JBossResourceException("SQLException", e);
}
|
protected void checkState() throws SQLException {
synchronized (stateLock)
{
// Check readonly
if (jdbcReadOnly != underlyingReadOnly)
{
con.setReadOnly(jdbcReadOnly);
underlyingReadOnly = jdbcReadOnly;
}
}
}
|
void checkTransaction() throws SQLException {
synchronized (stateLock)
{
if (inManagedTransaction)
return;
// Check autocommit
if (jdbcAutoCommit != underlyingAutoCommit)
{
con.setAutoCommit(jdbcAutoCommit);
underlyingAutoCommit = jdbcAutoCommit;
}
}
if (jdbcAutoCommit == false && inLocalTransaction.set(true) == false)
{
ArrayList copy;
synchronized (cels)
{
copy = new ArrayList(cels);
}
ConnectionEvent ce = new ConnectionEvent(this, ConnectionEvent.LOCAL_TRANSACTION_STARTED);
for (int i = 0; i < copy.size(); ++i)
{
ConnectionEventListener cel = (ConnectionEventListener) copy.get(i);
try
{
cel.localTransactionStarted(ce);
}
catch (Throwable t)
{
getLog().trace("Error notifying of connection committed for listener: " + cel, t);
}
}
}
checkState();
}
The checkTransaction method makes sure the adapter follows the JCA
autocommit contract, namely all statements executed outside a container managed transaction
or a component managed transaction should be autocommitted. To avoid continually calling
setAutocommit(enable) before and after container managed transactions, we keep track of the state
and check it before each transactional method call. |
public boolean checkValid() {
SQLException e = mcf.isValidConnection(con);
if (e == null)
// It's ok
return true;
else
{
getLog().warn("Destroying connection that is not valid, due to the following exception: " + con, e);
broadcastConnectionError(e);
return false;
}
}
|
public void cleanup() throws ResourceException {
synchronized (handles)
{
for (Iterator i = handles.iterator(); i.hasNext();)
{
WrappedConnection lc = (WrappedConnection) i.next();
lc.setManagedConnection(null);
}
handles.clear();
}
//reset all the properties we know about to defaults.
synchronized (stateLock)
{
jdbcAutoCommit = true;
jdbcReadOnly = readOnly;
if (jdbcTransactionIsolation != transactionIsolation)
{
try
{
con.setTransactionIsolation(jdbcTransactionIsolation);
jdbcTransactionIsolation = transactionIsolation;
}
catch (SQLException e)
{
mcf.log.warn("Error resetting transaction isolation ", e);
}
}
}
// I'm recreating the lock object when we return to the pool
// because it looks too nasty to expect the connection handle
// to unlock properly in certain race conditions
// where the dissociation of the managed connection is "random".
lock = new ReentrantLock();
}
|
void closeHandle(WrappedConnection handle) {
synchronized (stateLock)
{
if (destroyed)
return;
}
synchronized (handles)
{
handles.remove(handle);
}
ConnectionEvent ce = new ConnectionEvent(this, ConnectionEvent.CONNECTION_CLOSED);
ce.setConnectionHandle(handle);
Collection copy = null;
synchronized (cels)
{
copy = new ArrayList(cels);
}
for (Iterator i = copy.iterator(); i.hasNext();)
{
ConnectionEventListener cel = (ConnectionEventListener) i.next();
cel.connectionClosed(ce);
}
}
|
Throwable connectionError(Throwable t) {
if(t instanceof SQLException)
{
if(mcf.isStaleConnection((SQLException)t))
{
t = new StaleConnectionException((SQLException)t);
}else
{
if(mcf.isExceptionFatal((SQLException)t))
{
broadcastConnectionError(t);
}
}
}
else
{
broadcastConnectionError(t);
}
return t;
}
|
public void destroy() throws ResourceException {
synchronized (stateLock)
{
destroyed = true;
}
cleanup();
try
{
// See JBAS-5678
if (underlyingAutoCommit == false)
con.rollback();
}
catch (SQLException ignored)
{
getLog().trace("Ignored error during rollback: ", ignored);
}
try
{
con.close();
}
catch (SQLException ignored)
{
getLog().trace("Ignored error during close: ", ignored);
}
}
|
CallableStatement doPrepareCall(String sql,
int resultSetType,
int resultSetConcurrency) throws SQLException {
return con.prepareCall(sql, resultSetType, resultSetConcurrency);
}
|
PreparedStatement doPrepareStatement(String sql,
int resultSetType,
int resultSetConcurrency) throws SQLException {
return con.prepareStatement(sql, resultSetType, resultSetConcurrency);
}
|
Connection getConnection() throws SQLException {
if (con == null)
throw new SQLException("Connection has been destroyed!!!");
return con;
}
|
public Object getConnection(Subject subject,
ConnectionRequestInfo cri) throws ResourceException {
checkIdentity(subject, cri);
WrappedConnection lc = wrappedConnectionFactory.createWrappedConnection(this);
synchronized (handles)
{
handles.add(lc);
}
return lc;
}
|
int getJdbcTransactionIsolation() {
return jdbcTransactionIsolation;
}
|
protected Logger getLog() {
return mcf.log;
}
|
public PrintWriter getLogWriter() throws ResourceException {
// TODO: implement this javax.resource.spi.ManagedConnection method
return null;
}
|
public ManagedConnectionMetaData getMetaData() throws ResourceException {
// TODO: implement this javax.resource.spi.ManagedConnection method
return null;
}
|
public Properties getProperties() {
return this.props;
}
|
int getQueryTimeout() {
return mcf.getQueryTimeout();
}
|
int getTrackStatements() {
return mcf.trackStatements;
}
|
boolean isJdbcAutoCommit() {
return inManagedTransaction ? false : jdbcAutoCommit;
}
|
boolean isJdbcReadOnly() {
return jdbcReadOnly;
}
|
boolean isTransactionQueryTimeout() {
return mcf.isTransactionQueryTimeout;
}
|
void jdbcCommit() throws SQLException {
synchronized (stateLock)
{
if (inManagedTransaction)
throw new SQLException("You cannot commit during a managed transaction!");
if (jdbcAutoCommit)
throw new SQLException("You cannot commit with autocommit set!");
}
con.commit();
if (inLocalTransaction.set(false))
{
ArrayList copy;
synchronized (cels)
{
copy = new ArrayList(cels);
}
ConnectionEvent ce = new ConnectionEvent(this, ConnectionEvent.LOCAL_TRANSACTION_COMMITTED);
for (int i = 0; i < copy.size(); ++i)
{
ConnectionEventListener cel = (ConnectionEventListener) copy.get(i);
try
{
cel.localTransactionCommitted(ce);
}
catch (Throwable t)
{
getLog().trace("Error notifying of connection committed for listener: " + cel, t);
}
}
}
}
|
void jdbcRollback() throws SQLException {
synchronized (stateLock)
{
if (inManagedTransaction)
throw new SQLException("You cannot rollback during a managed transaction!");
if (jdbcAutoCommit)
throw new SQLException("You cannot rollback with autocommit set!");
}
con.rollback();
if (inLocalTransaction.set(false))
{
ArrayList copy;
synchronized (cels)
{
copy = new ArrayList(cels);
}
ConnectionEvent ce = new ConnectionEvent(this, ConnectionEvent.LOCAL_TRANSACTION_ROLLEDBACK);
for (int i = 0; i < copy.size(); ++i)
{
ConnectionEventListener cel = (ConnectionEventListener) copy.get(i);
try
{
cel.localTransactionRolledback(ce);
}
catch (Throwable t)
{
getLog().trace("Error notifying of connection rollback for listener: " + cel, t);
}
}
}
}
|
void jdbcRollback(Savepoint savepoint) throws SQLException {
synchronized (stateLock)
{
if (inManagedTransaction)
throw new SQLException("You cannot rollback during a managed transaction!");
if (jdbcAutoCommit)
throw new SQLException("You cannot rollback with autocommit set!");
}
con.rollback(savepoint);
}
|
public Object listConnectionStats() {
if(psCache != null)
return psCache.toString();
else
return "-1"; //-1 indicates NoCache
}
|
protected void lock() {
lock.lock();
}
|
CallableStatement prepareCall(String sql,
int resultSetType,
int resultSetConcurrency) throws SQLException {
if (psCache != null)
{
PreparedStatementCache.Key key = new PreparedStatementCache.Key(sql,
PreparedStatementCache.Key.CALLABLE_STATEMENT, resultSetType, resultSetConcurrency);
CachedCallableStatement cachedps = (CachedCallableStatement) psCache.get(key);
if (cachedps != null)
{
if (canUse(cachedps))
cachedps.inUse();
else
return doPrepareCall(sql, resultSetType, resultSetConcurrency);
}
else
{
CallableStatement cs = doPrepareCall(sql, resultSetType, resultSetConcurrency);
cachedps = wrappedConnectionFactory.createCachedCallableStatement(cs);
psCache.insert(key, cachedps);
}
return cachedps;
}
else
return doPrepareCall(sql, resultSetType, resultSetConcurrency);
}
|
PreparedStatement prepareStatement(String sql,
int resultSetType,
int resultSetConcurrency) throws SQLException {
if (psCache != null)
{
PreparedStatementCache.Key key = new PreparedStatementCache.Key(sql,
PreparedStatementCache.Key.PREPARED_STATEMENT, resultSetType, resultSetConcurrency);
CachedPreparedStatement cachedps = (CachedPreparedStatement) psCache.get(key);
if (cachedps != null)
{
if (canUse(cachedps))
cachedps.inUse();
else
return doPrepareStatement(sql, resultSetType, resultSetConcurrency);
}
else
{
PreparedStatement ps = doPrepareStatement(sql, resultSetType, resultSetConcurrency);
cachedps = wrappedConnectionFactory.createCachedPreparedStatement(ps);
psCache.insert(key, cachedps);
}
return cachedps;
}
else
return doPrepareStatement(sql, resultSetType, resultSetConcurrency);
}
|
public void removeConnectionEventListener(ConnectionEventListener cel) {
synchronized (cels)
{
cels.remove(cel);
}
}
|
void setJdbcAutoCommit(boolean jdbcAutoCommit) throws SQLException {
synchronized (stateLock)
{
if (inManagedTransaction)
throw new SQLException("You cannot set autocommit during a managed transaction!");
this.jdbcAutoCommit = jdbcAutoCommit;
}
if (jdbcAutoCommit && inLocalTransaction.set(false))
{
ArrayList copy;
synchronized (cels)
{
copy = new ArrayList(cels);
}
ConnectionEvent ce = new ConnectionEvent(this, ConnectionEvent.LOCAL_TRANSACTION_COMMITTED);
for (int i = 0; i < copy.size(); ++i)
{
ConnectionEventListener cel = (ConnectionEventListener) copy.get(i);
try
{
cel.localTransactionCommitted(ce);
}
catch (Throwable t)
{
getLog().trace("Error notifying of connection committed for listener: " + cel, t);
}
}
}
}
|
void setJdbcReadOnly(boolean readOnly) throws SQLException {
synchronized (stateLock)
{
if (inManagedTransaction)
throw new SQLException("You cannot set read only during a managed transaction!");
this.jdbcReadOnly = readOnly;
}
}
|
void setJdbcTransactionIsolation(int isolationLevel) throws SQLException {
synchronized (stateLock)
{
this.jdbcTransactionIsolation = isolationLevel;
con.setTransactionIsolation(jdbcTransactionIsolation);
}
}
|
public void setLogWriter(PrintWriter param1) throws ResourceException {
// TODO: implement this javax.resource.spi.ManagedConnection method
}
|
protected void tryLock() throws SQLException {
int tryLock = mcf.getUseTryLock();
if (tryLock < = 0)
{
lock();
return;
}
try
{
if (lock.tryLock(tryLock, TimeUnit.SECONDS) == false)
throw new SQLException("Unable to obtain lock in " + tryLock + " seconds: " + this);
}
catch (InterruptedException e)
{
throw new SQLException("Interrupted attempting lock: " + this);
}
}
|
protected void unlock() {
lock.unlock();
}
|