com.microsoft.sqlserver.jdbc.SQLServerXADataSource Maven / Gradle / Ivy
Show all versions of mssql-jdbc Show documentation
/*
* Microsoft JDBC Driver for SQL Server Copyright(c) Microsoft Corporation All rights reserved. This program is made
* available under the terms of the MIT License. See the LICENSE file in the project root for more information.
*/
package com.microsoft.sqlserver.jdbc;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.Reference;
import javax.sql.XAConnection;
import javax.sql.XADataSource;
/**
* Provides database connections for use in distributed (XA) transactions. SQLServerXADataSource also supports
* connection pooling of physical connections.
*
* The XADataSource and XAConnection interfaces, which are defined in the package javax.sql, are implemented by
* sqlserver. An XAConnection object is a pooled connection that can participate in a distributed transaction. More
* precisely, XAConnection extends the PooledConnection interface by adding the method getXAResource. This method
* produces an XAResource object that can be used by a transaction manager to coordinate the work done on this
* connection with the other participants in the distributed transaction.
*
*
* Because they extend the PooledConnection interface, XAConnection objects support all the methods of PooledConnection
* objects. They are reusable physical connections to an underlying data source and produce logical connection handles
* that can be passed back to a JDBC application.
*
*
* XAConnection objects are produced by an XADataSource object. There is some similarity between
* ConnectionPoolDataSource objects and XADataSource objects in that they are both implemented below a DataSource layer
* that is visible to the JDBC application. This architecture allows sqlserver to support distributed transactions in a
* way that is transparent to the application.
*
*
*
* SQLServerXADataSource can be configured to integrate with Microsoft Distributed Transaction Coordinator (DTC) to
* provide true, distributed transaction processing.
*/
public final class SQLServerXADataSource extends SQLServerConnectionPoolDataSource implements XADataSource {
static Logger xaLogger = Logger.getLogger("com.microsoft.sqlserver.jdbc.internals.XA");
/**
* default constructor
*/
public SQLServerXADataSource() {}
/**
* Returns a physical database connection to particate in an XA transaction with the specified user and password.
* This API should only be called by XA connection pool implementations, not regular JDBC application code.
*
* @return A new XAConnection
* @exception SQLException
* The database connection failed.
*/
@Override
public XAConnection getXAConnection(String user, String password) throws SQLException {
if (loggerExternal.isLoggable(Level.FINER))
loggerExternal.entering(getClassNameLogging(), "getXAConnection",
new Object[] {user, "Password not traced"});
SQLServerXAConnection pooledXAConnection = new SQLServerXAConnection(this, user, password);
if (xaLogger.isLoggable(Level.FINER))
xaLogger.finer(toString() + " user:" + user + pooledXAConnection.toString());
// Don't start a transaction here but do mark the connection as autocommit false.
// We cannot start a transaction since XA transaction type 'NEVER' does not start a transaction
// Autocommit of false is required to ensure that the transaction manager's calls to commit and
// rollback work correctly.
if (xaLogger.isLoggable(Level.FINER))
xaLogger.finer(toString() + " Start get physical connection.");
SQLServerConnection physicalConnection = pooledXAConnection.getPhysicalConnection();
if (xaLogger.isLoggable(Level.FINE))
xaLogger.fine(toString() + " End get physical connection, " + physicalConnection.toString());
if (loggerExternal.isLoggable(Level.FINER))
loggerExternal.exiting(getClassNameLogging(), "getXAConnection", pooledXAConnection);
return pooledXAConnection;
}
/**
* Returns a physical database connection to particate in an XA transaction. This API should only be called by XA
* connection pool implementations, not regular JDBC application code.
*
* @return A new XAConnection
* @exception SQLException
* The database connection failed.
*/
@Override
public XAConnection getXAConnection() throws SQLException {
if (loggerExternal.isLoggable(Level.FINER))
loggerExternal.entering(getClassNameLogging(), "getXAConnection");
return getXAConnection(getUser(), getPassword());
}
// Implement javax.naming.Referenceable interface methods.
@Override
public Reference getReference() {
if (loggerExternal.isLoggable(Level.FINER))
loggerExternal.entering(getClassNameLogging(), "getReference");
Reference ref = getReferenceInternal("com.microsoft.sqlserver.jdbc.SQLServerXADataSource");
if (loggerExternal.isLoggable(Level.FINER))
loggerExternal.exiting(getClassNameLogging(), "getReference", ref);
return ref;
}
/**
* writeReplace
*
* @return serialization proxy
* @throws java.io.ObjectStreamException
* if error
*/
private Object writeReplace() throws java.io.ObjectStreamException {
return new SerializationProxy(this);
}
/**
* For added security/robustness, the only way to rehydrate a serialized SQLServerXADataSource is to use a
* SerializationProxy. Direct use of readObject() is not supported.
*
* @param stream
* input stream object
* @throws java.io.InvalidObjectException
* if error
*/
private void readObject(java.io.ObjectInputStream stream) throws java.io.InvalidObjectException {
throw new java.io.InvalidObjectException("");
}
/**
* Implements java.io.Serializable the same way as {@link SQLServerDataSource}
*/
private static class SerializationProxy implements java.io.Serializable {
private final Reference ref;
private static final long serialVersionUID = 454661379842314126L;
SerializationProxy(SQLServerXADataSource ds) {
// We do not need the class name so pass null, serialization mechanism
// stores the class info.
ref = ds.getReferenceInternal(null);
}
private Object readResolve() {
SQLServerXADataSource ds = new SQLServerXADataSource();
ds.initializeFromReference(ref);
return ds;
}
}
}