SPRNET-1398
Change default value for timeout field to non-zero
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
#region License
|
||||
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright <20> 2002-2006 the original author or authors.
|
||||
*
|
||||
@@ -14,106 +14,106 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Data;
|
||||
using Spring.Data.Common;
|
||||
using Spring.Data.Support;
|
||||
using Spring.Objects.Factory;
|
||||
|
||||
namespace Spring.Data.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for AdoTemplate and other ADO.NET DAO helper classes defining
|
||||
/// common properties like DbProvider.
|
||||
/// </summary>
|
||||
/// <author>Mark Pollack (.NET)</author>
|
||||
/// <author>Juergen Hoeller</author>
|
||||
public abstract class AdoAccessor : IInitializingObject
|
||||
{
|
||||
protected object AdoUtils;
|
||||
|
||||
protected int commandTimeout;
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// An instance of a DbProvider implementation.
|
||||
/// </summary>
|
||||
public abstract IDbProvider DbProvider
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether to lazily initialize the
|
||||
/// IAdoExceptionTranslator for this accessor, on first encounter of a
|
||||
/// exception from the data provider. Default is "true"; can be switched to
|
||||
/// "false" for initialization on startup.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if to lazy initialize the IAdoExceptionTranslator;
|
||||
/// otherwise, <c>false</c>.</value>
|
||||
public abstract bool LazyInit
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the exception translator. If no custom translator is provided, a default
|
||||
/// <see cref="ErrorCodeExceptionTranslator"/> is used.
|
||||
/// </summary>
|
||||
/// <value>The exception translator.</value>
|
||||
public abstract IAdoExceptionTranslator ExceptionTranslator
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or set the System.Type to use to create an instance of IDataReaderWrapper
|
||||
/// for the purpose of having defaults values to use in case of DBNull values read
|
||||
/// from IDataReader.
|
||||
/// </summary>
|
||||
/// <value>The type of the data reader wrapper.</value>
|
||||
public abstract Type DataReaderWrapperType
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the command timeout for IDbCommands that this AdoTemplate executes.
|
||||
/// </summary>
|
||||
/// <remarks>Default is 0, indicating to use the database provider's default.
|
||||
/// Any timeout specified here will be overridden by the remaining
|
||||
/// transaction timeout when executing within a transaction that has a
|
||||
/// timeout specified at the transaction level.
|
||||
/// </remarks>
|
||||
/// <value>The command timeout.</value>
|
||||
public virtual int CommandTimeout
|
||||
{
|
||||
get { return commandTimeout; }
|
||||
set { commandTimeout = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Prepare the command setting the transaction timeout.
|
||||
/// </summary>
|
||||
/// <param name="command"></param>
|
||||
protected virtual void ApplyCommandSettings(IDbCommand command)
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Data;
|
||||
using Spring.Data.Common;
|
||||
using Spring.Data.Support;
|
||||
using Spring.Objects.Factory;
|
||||
|
||||
namespace Spring.Data.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for AdoTemplate and other ADO.NET DAO helper classes defining
|
||||
/// common properties like DbProvider.
|
||||
/// </summary>
|
||||
/// <author>Mark Pollack (.NET)</author>
|
||||
/// <author>Juergen Hoeller</author>
|
||||
public abstract class AdoAccessor : IInitializingObject
|
||||
{
|
||||
protected object AdoUtils;
|
||||
|
||||
protected int commandTimeout = -1;
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// An instance of a DbProvider implementation.
|
||||
/// </summary>
|
||||
public abstract IDbProvider DbProvider
|
||||
{
|
||||
Support.ConnectionUtils.ApplyTransactionTimeout(command, DbProvider, CommandTimeout);
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether to lazily initialize the
|
||||
/// IAdoExceptionTranslator for this accessor, on first encounter of a
|
||||
/// exception from the data provider. Default is "true"; can be switched to
|
||||
/// "false" for initialization on startup.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if to lazy initialize the IAdoExceptionTranslator;
|
||||
/// otherwise, <c>false</c>.</value>
|
||||
public abstract bool LazyInit
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the exception translator. If no custom translator is provided, a default
|
||||
/// <see cref="ErrorCodeExceptionTranslator"/> is used.
|
||||
/// </summary>
|
||||
/// <value>The exception translator.</value>
|
||||
public abstract IAdoExceptionTranslator ExceptionTranslator
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or set the System.Type to use to create an instance of IDataReaderWrapper
|
||||
/// for the purpose of having defaults values to use in case of DBNull values read
|
||||
/// from IDataReader.
|
||||
/// </summary>
|
||||
/// <value>The type of the data reader wrapper.</value>
|
||||
public abstract Type DataReaderWrapperType
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the command timeout for IDbCommands that this AdoTemplate executes.
|
||||
/// </summary>
|
||||
/// <remarks>Default is 0, indicating to use the database provider's default.
|
||||
/// Any timeout specified here will be overridden by the remaining
|
||||
/// transaction timeout when executing within a transaction that has a
|
||||
/// timeout specified at the transaction level.
|
||||
/// </remarks>
|
||||
/// <value>The command timeout.</value>
|
||||
public virtual int CommandTimeout
|
||||
{
|
||||
get { return commandTimeout; }
|
||||
set { commandTimeout = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Prepare the command setting the transaction timeout.
|
||||
/// </summary>
|
||||
/// <param name="command"></param>
|
||||
protected virtual void ApplyCommandSettings(IDbCommand command)
|
||||
{
|
||||
Support.ConnectionUtils.ApplyTransactionTimeout(command, DbProvider, CommandTimeout);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -130,22 +130,22 @@ namespace Spring.Data.Core
|
||||
protected virtual void DisposeDataAdapterCommands(IDbDataAdapter adapter)
|
||||
{
|
||||
Support.AdoUtils.DisposeDataAdapterCommands(adapter);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extract the command text from the given <see cref="ICommandTextProvider"/>, if any.
|
||||
/// </summary>
|
||||
protected virtual string GetCommandText(object cmdTextProvider)
|
||||
{
|
||||
ICommandTextProvider commandTextProvider = cmdTextProvider as ICommandTextProvider;
|
||||
if (commandTextProvider != null)
|
||||
{
|
||||
return commandTextProvider.CommandText;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
protected virtual string GetCommandText(object cmdTextProvider)
|
||||
{
|
||||
ICommandTextProvider commandTextProvider = cmdTextProvider as ICommandTextProvider;
|
||||
if (commandTextProvider != null)
|
||||
{
|
||||
return commandTextProvider.CommandText;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -155,95 +155,95 @@ namespace Spring.Data.Core
|
||||
{
|
||||
return Support.ConnectionUtils.GetConnectionTxPair(provider);
|
||||
}
|
||||
|
||||
protected virtual void DisposeConnection(IDbConnection connection, IDbProvider provider)
|
||||
|
||||
protected virtual void DisposeConnection(IDbConnection connection, IDbProvider provider)
|
||||
{
|
||||
Support.ConnectionUtils.DisposeConnection(connection, provider);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked by an <see cref="Spring.Objects.Factory.IObjectFactory"/>
|
||||
/// after it has injected all of an object's dependencies.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This method allows the object instance to perform the kind of
|
||||
/// initialization only possible when all of it's dependencies have
|
||||
/// been injected (set), and to throw an appropriate exception in the
|
||||
/// event of misconfiguration.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// Please do consult the class level documentation for the
|
||||
/// <see cref="Spring.Objects.Factory.IObjectFactory"/> interface for a
|
||||
/// description of exactly <i>when</i> this method is invoked. In
|
||||
/// particular, it is worth noting that the
|
||||
/// <see cref="Spring.Objects.Factory.IObjectFactoryAware"/>
|
||||
/// and <see cref="Spring.Context.IApplicationContextAware"/>
|
||||
/// callbacks will have been invoked <i>prior</i> to this method being
|
||||
/// called.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <exception cref="System.Exception">
|
||||
/// In the event of misconfiguration (such as the failure to set a
|
||||
/// required property) or if initialization fails.
|
||||
/// </exception>
|
||||
public abstract void AfterPropertiesSet();
|
||||
|
||||
/// <summary>
|
||||
/// Creates the data reader wrapper for use in AdoTemplate callback methods.
|
||||
/// </summary>
|
||||
/// <param name="readerToWrap">The reader to wrap.</param>
|
||||
/// <returns>The data reader used in AdoTemplate callbacks</returns>
|
||||
public abstract IDataReader CreateDataReaderWrapper(IDataReader readerToWrap);
|
||||
|
||||
/// <summary>
|
||||
/// Creates the a db parameters collection, adding to the collection a parameter created from
|
||||
/// the method parameters.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the parameter</param>
|
||||
/// <param name="dbType">The type of the parameter.</param>
|
||||
/// <param name="size">The size of the parameter, for use in defining lengths of string values. Use
|
||||
/// 0 if not applicable.</param>
|
||||
/// <param name="parameterValue">The parameter value.</param>
|
||||
/// <returns>A collection of db parameters with a single parameter in the collection based
|
||||
/// on the method parameters</returns>
|
||||
protected IDbParameters CreateDbParameters(string name, Enum dbType, int size, object parameterValue)
|
||||
{
|
||||
IDbParameters parameters = new DbParameters(DbProvider);
|
||||
parameters.Add(name, dbType, size).Value = parameterValue;
|
||||
return parameters;
|
||||
}
|
||||
|
||||
|
||||
#region Parameter Creation Helper Methods
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="DbParameters"/>
|
||||
/// </summary>
|
||||
/// <returns>a new instance of <see cref="DbParameters"/></returns>
|
||||
public virtual IDbParameters CreateDbParameters()
|
||||
{
|
||||
return new DbParameters(DbProvider);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Derives the parameters of a stored procedure, not including the return parameter.
|
||||
/// </summary>
|
||||
/// <param name="procedureName">Name of the procedure.</param>
|
||||
/// <returns>The stored procedure parameters.</returns>
|
||||
public virtual IDataParameter[] DeriveParameters(string procedureName)
|
||||
{
|
||||
return DeriveParameters(procedureName, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Derives the parameters of a stored procedure including the return parameter
|
||||
/// </summary>
|
||||
/// <param name="procedureName">Name of the procedure.</param>
|
||||
/// <param name="includeReturnParameter">if set to <c>true</c> to include return parameter.</param>
|
||||
/// <returns>The stored procedure parameters</returns>
|
||||
public abstract IDataParameter[] DeriveParameters(string procedureName, bool includeReturnParameter);
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked by an <see cref="Spring.Objects.Factory.IObjectFactory"/>
|
||||
/// after it has injected all of an object's dependencies.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This method allows the object instance to perform the kind of
|
||||
/// initialization only possible when all of it's dependencies have
|
||||
/// been injected (set), and to throw an appropriate exception in the
|
||||
/// event of misconfiguration.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// Please do consult the class level documentation for the
|
||||
/// <see cref="Spring.Objects.Factory.IObjectFactory"/> interface for a
|
||||
/// description of exactly <i>when</i> this method is invoked. In
|
||||
/// particular, it is worth noting that the
|
||||
/// <see cref="Spring.Objects.Factory.IObjectFactoryAware"/>
|
||||
/// and <see cref="Spring.Context.IApplicationContextAware"/>
|
||||
/// callbacks will have been invoked <i>prior</i> to this method being
|
||||
/// called.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <exception cref="System.Exception">
|
||||
/// In the event of misconfiguration (such as the failure to set a
|
||||
/// required property) or if initialization fails.
|
||||
/// </exception>
|
||||
public abstract void AfterPropertiesSet();
|
||||
|
||||
/// <summary>
|
||||
/// Creates the data reader wrapper for use in AdoTemplate callback methods.
|
||||
/// </summary>
|
||||
/// <param name="readerToWrap">The reader to wrap.</param>
|
||||
/// <returns>The data reader used in AdoTemplate callbacks</returns>
|
||||
public abstract IDataReader CreateDataReaderWrapper(IDataReader readerToWrap);
|
||||
|
||||
/// <summary>
|
||||
/// Creates the a db parameters collection, adding to the collection a parameter created from
|
||||
/// the method parameters.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the parameter</param>
|
||||
/// <param name="dbType">The type of the parameter.</param>
|
||||
/// <param name="size">The size of the parameter, for use in defining lengths of string values. Use
|
||||
/// 0 if not applicable.</param>
|
||||
/// <param name="parameterValue">The parameter value.</param>
|
||||
/// <returns>A collection of db parameters with a single parameter in the collection based
|
||||
/// on the method parameters</returns>
|
||||
protected IDbParameters CreateDbParameters(string name, Enum dbType, int size, object parameterValue)
|
||||
{
|
||||
IDbParameters parameters = new DbParameters(DbProvider);
|
||||
parameters.Add(name, dbType, size).Value = parameterValue;
|
||||
return parameters;
|
||||
}
|
||||
|
||||
|
||||
#region Parameter Creation Helper Methods
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="DbParameters"/>
|
||||
/// </summary>
|
||||
/// <returns>a new instance of <see cref="DbParameters"/></returns>
|
||||
public virtual IDbParameters CreateDbParameters()
|
||||
{
|
||||
return new DbParameters(DbProvider);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Derives the parameters of a stored procedure, not including the return parameter.
|
||||
/// </summary>
|
||||
/// <param name="procedureName">Name of the procedure.</param>
|
||||
/// <returns>The stored procedure parameters.</returns>
|
||||
public virtual IDataParameter[] DeriveParameters(string procedureName)
|
||||
{
|
||||
return DeriveParameters(procedureName, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Derives the parameters of a stored procedure including the return parameter
|
||||
/// </summary>
|
||||
/// <param name="procedureName">Name of the procedure.</param>
|
||||
/// <param name="includeReturnParameter">if set to <c>true</c> to include return parameter.</param>
|
||||
/// <returns>The stored procedure parameters</returns>
|
||||
public abstract IDataParameter[] DeriveParameters(string procedureName, bool includeReturnParameter);
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#region License
|
||||
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright <20> 2002-2005 the original author or authors.
|
||||
*
|
||||
@@ -14,231 +14,233 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Data;
|
||||
using Common.Logging;
|
||||
using Spring.Data.Common;
|
||||
using Spring.Transaction.Support;
|
||||
using Spring.Util;
|
||||
|
||||
namespace Spring.Data.Support
|
||||
{
|
||||
/// <summary>
|
||||
/// Summary description for DbProviderUtils.
|
||||
/// </summary>
|
||||
public abstract class ConnectionUtils
|
||||
{
|
||||
#region Logging
|
||||
|
||||
private static readonly ILog LOG = LogManager.GetLogger(typeof (ConnectionUtils));
|
||||
|
||||
#endregion
|
||||
|
||||
public static readonly int CONNECTION_SYNCHRONIZATION_ORDER = 1000;
|
||||
/// <summary>
|
||||
/// Dispose of the given Connection, created via the given IDbProvider,
|
||||
/// if it is not managed externally (that is, not bound to the thread).
|
||||
/// </summary>
|
||||
/// <param name="conn">The connection to close if necessary. If
|
||||
/// this is null the call will be ignored. </param>
|
||||
/// <param name="dbProvider">The IDbProvider the connection came from</param>
|
||||
public static void DisposeConnection(IDbConnection conn, IDbProvider dbProvider)
|
||||
{
|
||||
try
|
||||
{
|
||||
DoDisposeConnection(conn, dbProvider);
|
||||
} catch (Exception e)
|
||||
{
|
||||
LOG.Warn("Could not close connection", e);
|
||||
}
|
||||
|
||||
}
|
||||
private static void DoDisposeConnection(IDbConnection conn, IDbProvider dbProvider)
|
||||
{
|
||||
if (conn == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (dbProvider != null)
|
||||
{
|
||||
ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.GetResource(dbProvider);
|
||||
if (conHolder != null && ConnectionEquals(conHolder.Connection, conn))
|
||||
{
|
||||
// It's the transactional connection bound to the thread so don't close it.
|
||||
conHolder.Released();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (LOG.IsDebugEnabled)
|
||||
{
|
||||
LOG.Debug("Disposing of IDbConnection with connection string = [" + dbProvider.ConnectionString + "]");
|
||||
}
|
||||
conn.Dispose();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get a ADO.NET Connection/Transaction Pair for the given IDbProvider.
|
||||
/// Changes any exception into the Spring hierarchy of generic data access
|
||||
/// exceptions, simplifying calling code and making any exception that is
|
||||
/// thrown more meaningful.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Is aware of a corresponding Connection/Transaction bound to the current thread, for example
|
||||
/// when using AdoPlatformTransactionManager. Will bind a IDbConnection to the thread
|
||||
/// if transaction synchronization is active
|
||||
/// </remarks>
|
||||
/// <param name="provider">The provider.</param>
|
||||
/// <returns>A Connection/Transaction pair.</returns>
|
||||
public static ConnectionTxPair GetConnectionTxPair(IDbProvider provider)
|
||||
{
|
||||
try
|
||||
{
|
||||
return DoGetConnection(provider);
|
||||
} catch (Exception e)
|
||||
{
|
||||
throw new CannotGetAdoConnectionException("Could not get ADO.NET connection.", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get a ADO.NET Connection/Transaction Pair for the given IDbProvider.
|
||||
/// Same as <see cref="GetConnection"/> but throwing original provider
|
||||
/// exception.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Is aware of a corresponding Connection/Transaction bound to the current thread, for example
|
||||
/// when using AdoPlatformTransactionManager. Will bind a IDbConnection to the thread
|
||||
/// if transaction synchronization is active
|
||||
/// </remarks>
|
||||
/// <param name="provider">The provider.</param>
|
||||
/// <returns></returns>
|
||||
public static ConnectionTxPair DoGetConnection(IDbProvider provider)
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(provider, "provider");
|
||||
ConnectionHolder conHolder = (ConnectionHolder)TransactionSynchronizationManager.GetResource(provider);
|
||||
if (conHolder != null && (conHolder.HasConnection || conHolder.SynchronizedWithTransaction))
|
||||
{
|
||||
conHolder.Requested();
|
||||
if (!conHolder.HasConnection)
|
||||
{
|
||||
if (LOG.IsDebugEnabled)
|
||||
{
|
||||
LOG.Debug("Fetching resumed ADO.NET connection from DbProvider");
|
||||
}
|
||||
conHolder.Connection = provider.CreateConnection();
|
||||
}
|
||||
return new ConnectionTxPair(conHolder.Connection, conHolder.Transaction);
|
||||
}
|
||||
|
||||
// Else we either got no holder or an empty thread-bound holder here.
|
||||
if (LOG.IsDebugEnabled)
|
||||
{
|
||||
LOG.Debug("Fetching Connection from DbProvider");
|
||||
}
|
||||
IDbConnection conn = provider.CreateConnection();
|
||||
conn.Open();
|
||||
|
||||
if (TransactionSynchronizationManager.SynchronizationActive)
|
||||
{
|
||||
LOG.Debug("Registering transaction synchronization for IDbConnection");
|
||||
//Use same connection for further ADO.NET actions with the transaction.
|
||||
//Thread-bound object will get removed by manager at transaction completion.
|
||||
|
||||
ConnectionHolder holderToUse = conHolder;
|
||||
if (holderToUse == null)
|
||||
{
|
||||
holderToUse = new ConnectionHolder(conn, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
holderToUse.Connection = conn;
|
||||
}
|
||||
holderToUse.Requested();
|
||||
TransactionSynchronizationManager.RegisterSynchronization(
|
||||
new ConnectionSynchronization(holderToUse, provider));
|
||||
holderToUse.SynchronizedWithTransaction = true;
|
||||
if (holderToUse != conHolder)
|
||||
{
|
||||
TransactionSynchronizationManager.BindResource(provider, holderToUse);
|
||||
}
|
||||
|
||||
}
|
||||
return new ConnectionTxPair(conn, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Do the connection mgmt.
|
||||
/// </summary>
|
||||
/// <param name="provider"></param>
|
||||
/// <returns></returns>
|
||||
public static IDbConnection GetConnection(IDbProvider provider)
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(provider, "provider");
|
||||
|
||||
return GetConnectionTxPair(provider).Connection;
|
||||
|
||||
}
|
||||
|
||||
private static bool ConnectionEquals(IDbConnection heldCon, IDbConnection passedInCon)
|
||||
{
|
||||
return (heldCon == passedInCon || heldCon.Equals(passedInCon) ||
|
||||
getTargetConnection(heldCon).Equals(passedInCon));
|
||||
}
|
||||
|
||||
private static IDbConnection getTargetConnection(IDbConnection con)
|
||||
{
|
||||
IDbConnection conToUse = con;
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Data;
|
||||
using Common.Logging;
|
||||
using Spring.Data.Common;
|
||||
using Spring.Transaction.Support;
|
||||
using Spring.Util;
|
||||
|
||||
namespace Spring.Data.Support
|
||||
{
|
||||
/// <summary>
|
||||
/// Summary description for DbProviderUtils.
|
||||
/// </summary>
|
||||
public abstract class ConnectionUtils
|
||||
{
|
||||
#region Logging
|
||||
|
||||
private static readonly ILog LOG = LogManager.GetLogger(typeof(ConnectionUtils));
|
||||
|
||||
#endregion
|
||||
|
||||
public static readonly int CONNECTION_SYNCHRONIZATION_ORDER = 1000;
|
||||
/// <summary>
|
||||
/// Dispose of the given Connection, created via the given IDbProvider,
|
||||
/// if it is not managed externally (that is, not bound to the thread).
|
||||
/// </summary>
|
||||
/// <param name="conn">The connection to close if necessary. If
|
||||
/// this is null the call will be ignored. </param>
|
||||
/// <param name="dbProvider">The IDbProvider the connection came from</param>
|
||||
public static void DisposeConnection(IDbConnection conn, IDbProvider dbProvider)
|
||||
{
|
||||
try
|
||||
{
|
||||
DoDisposeConnection(conn, dbProvider);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOG.Warn("Could not close connection", e);
|
||||
}
|
||||
|
||||
}
|
||||
private static void DoDisposeConnection(IDbConnection conn, IDbProvider dbProvider)
|
||||
{
|
||||
if (conn == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (dbProvider != null)
|
||||
{
|
||||
ConnectionHolder conHolder = (ConnectionHolder)TransactionSynchronizationManager.GetResource(dbProvider);
|
||||
if (conHolder != null && ConnectionEquals(conHolder.Connection, conn))
|
||||
{
|
||||
// It's the transactional connection bound to the thread so don't close it.
|
||||
conHolder.Released();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (LOG.IsDebugEnabled)
|
||||
{
|
||||
LOG.Debug("Disposing of IDbConnection with connection string = [" + dbProvider.ConnectionString + "]");
|
||||
}
|
||||
conn.Dispose();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get a ADO.NET Connection/Transaction Pair for the given IDbProvider.
|
||||
/// Changes any exception into the Spring hierarchy of generic data access
|
||||
/// exceptions, simplifying calling code and making any exception that is
|
||||
/// thrown more meaningful.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Is aware of a corresponding Connection/Transaction bound to the current thread, for example
|
||||
/// when using AdoPlatformTransactionManager. Will bind a IDbConnection to the thread
|
||||
/// if transaction synchronization is active
|
||||
/// </remarks>
|
||||
/// <param name="provider">The provider.</param>
|
||||
/// <returns>A Connection/Transaction pair.</returns>
|
||||
public static ConnectionTxPair GetConnectionTxPair(IDbProvider provider)
|
||||
{
|
||||
try
|
||||
{
|
||||
return DoGetConnection(provider);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new CannotGetAdoConnectionException("Could not get ADO.NET connection.", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get a ADO.NET Connection/Transaction Pair for the given IDbProvider.
|
||||
/// Same as <see cref="GetConnection"/> but throwing original provider
|
||||
/// exception.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Is aware of a corresponding Connection/Transaction bound to the current thread, for example
|
||||
/// when using AdoPlatformTransactionManager. Will bind a IDbConnection to the thread
|
||||
/// if transaction synchronization is active
|
||||
/// </remarks>
|
||||
/// <param name="provider">The provider.</param>
|
||||
/// <returns></returns>
|
||||
public static ConnectionTxPair DoGetConnection(IDbProvider provider)
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(provider, "provider");
|
||||
ConnectionHolder conHolder = (ConnectionHolder)TransactionSynchronizationManager.GetResource(provider);
|
||||
if (conHolder != null && (conHolder.HasConnection || conHolder.SynchronizedWithTransaction))
|
||||
{
|
||||
conHolder.Requested();
|
||||
if (!conHolder.HasConnection)
|
||||
{
|
||||
if (LOG.IsDebugEnabled)
|
||||
{
|
||||
LOG.Debug("Fetching resumed ADO.NET connection from DbProvider");
|
||||
}
|
||||
conHolder.Connection = provider.CreateConnection();
|
||||
}
|
||||
return new ConnectionTxPair(conHolder.Connection, conHolder.Transaction);
|
||||
}
|
||||
|
||||
// Else we either got no holder or an empty thread-bound holder here.
|
||||
if (LOG.IsDebugEnabled)
|
||||
{
|
||||
LOG.Debug("Fetching Connection from DbProvider");
|
||||
}
|
||||
IDbConnection conn = provider.CreateConnection();
|
||||
conn.Open();
|
||||
|
||||
if (TransactionSynchronizationManager.SynchronizationActive)
|
||||
{
|
||||
LOG.Debug("Registering transaction synchronization for IDbConnection");
|
||||
//Use same connection for further ADO.NET actions with the transaction.
|
||||
//Thread-bound object will get removed by manager at transaction completion.
|
||||
|
||||
ConnectionHolder holderToUse = conHolder;
|
||||
if (holderToUse == null)
|
||||
{
|
||||
holderToUse = new ConnectionHolder(conn, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
holderToUse.Connection = conn;
|
||||
}
|
||||
holderToUse.Requested();
|
||||
TransactionSynchronizationManager.RegisterSynchronization(
|
||||
new ConnectionSynchronization(holderToUse, provider));
|
||||
holderToUse.SynchronizedWithTransaction = true;
|
||||
if (holderToUse != conHolder)
|
||||
{
|
||||
TransactionSynchronizationManager.BindResource(provider, holderToUse);
|
||||
}
|
||||
|
||||
}
|
||||
return new ConnectionTxPair(conn, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Do the connection mgmt.
|
||||
/// </summary>
|
||||
/// <param name="provider"></param>
|
||||
/// <returns></returns>
|
||||
public static IDbConnection GetConnection(IDbProvider provider)
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(provider, "provider");
|
||||
|
||||
return GetConnectionTxPair(provider).Connection;
|
||||
|
||||
}
|
||||
|
||||
private static bool ConnectionEquals(IDbConnection heldCon, IDbConnection passedInCon)
|
||||
{
|
||||
return (heldCon == passedInCon || heldCon.Equals(passedInCon) ||
|
||||
getTargetConnection(heldCon).Equals(passedInCon));
|
||||
}
|
||||
|
||||
private static IDbConnection getTargetConnection(IDbConnection con)
|
||||
{
|
||||
IDbConnection conToUse = con;
|
||||
/*
|
||||
while (conToUse is ConnectionProxy)
|
||||
{
|
||||
conToUse = (ConnectionProxy)conToUse.getTargetConnection();
|
||||
}
|
||||
*/
|
||||
return conToUse;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies the current transaction timeout, if any, to the given ADO.NET IDbCommand object.
|
||||
/// </summary>
|
||||
/// <param name="command">The command.</param>
|
||||
/// <param name="dbProvider">The db provider.</param>
|
||||
public static void ApplyTransactionTimeout(IDbCommand command, IDbProvider dbProvider)
|
||||
{
|
||||
ApplyTransactionTimeout(command, dbProvider, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies the specified timeout - overridden by the current transaction timeout, if any, to to the
|
||||
/// given ADO.NET IDb command object.
|
||||
/// </summary>
|
||||
/// <param name="command">The command.</param>
|
||||
/// <param name="dbProvider">The db provider the command was obtained from.</param>
|
||||
/// <param name="timeout">The timeout to apply (or 0 for no timeout outside of a transaction.</param>
|
||||
public static void ApplyTransactionTimeout(IDbCommand command, IDbProvider dbProvider, int timeout)
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(command, "command", "No IDbCommand specified.");
|
||||
AssertUtils.ArgumentNotNull(dbProvider, "dbProvider", "No IDbProvider specified.");
|
||||
|
||||
ConnectionHolder conHolder = (ConnectionHolder)TransactionSynchronizationManager.GetResource(dbProvider);
|
||||
if (conHolder != null && conHolder.HasTimeout)
|
||||
{
|
||||
// Remaining transaction timeout overrides specified value.
|
||||
command.CommandTimeout = conHolder.TimeToLiveInSeconds;
|
||||
}
|
||||
else if (timeout >= 0)
|
||||
{
|
||||
// No current transaction timeout -> apply specified value. 0 = infinite timeout in some drivers.
|
||||
command.CommandTimeout = timeout;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
return conToUse;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies the current transaction timeout, if any, to the given ADO.NET IDbCommand object.
|
||||
/// </summary>
|
||||
/// <param name="command">The command.</param>
|
||||
/// <param name="dbProvider">The db provider.</param>
|
||||
public static void ApplyTransactionTimeout(IDbCommand command, IDbProvider dbProvider)
|
||||
{
|
||||
ApplyTransactionTimeout(command, dbProvider, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies the specified timeout - overridden by the current transaction timeout, if any, to to the
|
||||
/// given ADO.NET IDb command object.
|
||||
/// </summary>
|
||||
/// <param name="command">The command.</param>
|
||||
/// <param name="dbProvider">The db provider the command was obtained from.</param>
|
||||
/// <param name="timeout">The timeout to apply (or 0 for no timeout outside of a transaction.</param>
|
||||
public static void ApplyTransactionTimeout(IDbCommand command, IDbProvider dbProvider, int timeout)
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(command, "command", "No IDbCommand specified.");
|
||||
AssertUtils.ArgumentNotNull(dbProvider, "dbProvider", "No IDbProvider specified.");
|
||||
|
||||
ConnectionHolder conHolder = (ConnectionHolder)TransactionSynchronizationManager.GetResource(dbProvider);
|
||||
if (conHolder != null && conHolder.HasTimeout)
|
||||
{
|
||||
// Remaining transaction timeout overrides specified value.
|
||||
command.CommandTimeout = conHolder.TimeToLiveInSeconds;
|
||||
}
|
||||
else if (timeout != -1)
|
||||
{
|
||||
// No current transaction timeout -> apply specified value. 0 = infinite timeout in some drivers.
|
||||
command.CommandTimeout = timeout;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user