/// <summary> /// Begin a new transaction with the given transaction definition. /// </summary> /// <param name="transaction"> /// Transaction object returned by /// <see cref="Spring.Transaction.Support.AbstractPlatformTransactionManager.DoGetTransaction"/>. /// </param> /// <param name="definition"> /// <see cref="Spring.Transaction.ITransactionDefinition"/> instance, describing /// propagation behavior, isolation level, timeout etc. /// </param> /// <remarks> /// Does not have to care about applying the propagation behavior, /// as this has already been handled by this abstract manager. /// </remarks> /// <exception cref="Spring.Transaction.TransactionException"> /// In the case of creation or system errors. /// </exception> protected override void DoBegin(object transaction, ITransactionDefinition definition) { DbProviderTransactionObject txMgrStateObject = (DbProviderTransactionObject)transaction; IDbConnection con = null; if (dbProvider == null) { throw new ArgumentException("DbProvider is required to be set on AdoPlatformTransactionManager"); } try { if (txMgrStateObject.ConnectionHolder == null || txMgrStateObject.ConnectionHolder.SynchronizedWithTransaction) { IDbConnection newCon = DbProvider.CreateConnection(); if (log.IsDebugEnabled) { log.Debug("Acquired Connection [" + newCon + ", " + newCon.ConnectionString + "] for ADO.NET transaction"); } newCon.Open(); //TODO isolation level mgmt - will need to abstract out SQL used to specify this in DbMetaData //MSDN docs... //With one exception, you can switch from one isolation level to another at any time during a transaction. The exception occurs when changing from any isolation level to SNAPSHOT isolation //IsolationLevel previousIsolationLevel = IDbTransaction newTrans = newCon.BeginTransaction(definition.TransactionIsolationLevel); txMgrStateObject.SetConnectionHolder(new ConnectionHolder(newCon, newTrans), true); } txMgrStateObject.ConnectionHolder.SynchronizedWithTransaction = true; con = txMgrStateObject.ConnectionHolder.Connection; txMgrStateObject.ConnectionHolder.TransactionActive = true; int timeout = DetermineTimeout(definition); if (timeout != DefaultTransactionDefinition.TIMEOUT_DEFAULT) { txMgrStateObject.ConnectionHolder.TimeoutInSeconds = timeout; } //Bind transactional resources to thread if (txMgrStateObject.NewConnectionHolder) { TransactionSynchronizationManager.BindResource(DbProvider, txMgrStateObject.ConnectionHolder); } } //TODO catch specific exception catch (Exception e) { ConnectionUtils.DisposeConnection(con, DbProvider); throw new CannotCreateTransactionException("Could not create ADO.NET connection for transaction", e); } }
/// <summary> /// Create the ConnHolder by DbProvider. /// </summary> /// <returns></returns> protected override ConnectionHolder CreateConnectionHolder() { IDbConnection dbConnection = null; try { dbConnection = DbProvider.CreateConnection(); dbConnection.ConnectionString = DbProvider.ConnectionString; dbConnection.Open(); var connectionHolder = new ConnectionHolder(dbConnection, null); int timeout = DetermineTimeout(Definition); if (timeout != DefaultUnitOfWorkDefinition.TIMEOUT_DEFAULT) { connectionHolder.TimeoutInSeconds = timeout; } return(connectionHolder); } //TODO catch specific exception catch (Exception e) { ConnectionUtils.DisposeConnection(dbConnection, DbProvider); throw new CannotCreateConnectionHolderException("Could not create ADO.NET ConnectionHolder for transaction", e); } }
/// <summary> /// 针对<see cref="System.Data.IDbConnection"/>执行<see cref="System.Data.IDbCommand.CommandText"/>,并生成 /// <see cref="System.Data.IDataReader"/> /// </summary> /// <param name="connString">A ConnectionString.</param> /// <param name="commandType">the CommandType.</param> /// <param name="commandText">A execute Sql.</param> /// <param name="timeoutInSeconds">the dbcommand timeout.</param> /// <param name="parameterValues">the sql parameters.</param> /// <returns>a datareader.</returns> public IDataReader ExecuteReader(string connString, CommandType commandType, string commandText, int timeoutInSeconds, IDbParameters parameterValues) { AssertUtils.StringNotNullOrEmpty(connString, "connString"); ConnectionTxPair connectionTxPair = GetConnectionTxPair(connString); try { IDbCommand dbCommand = DbProvider.CreateCommand(); PrepareCommand(dbCommand, connectionTxPair.Connection, connectionTxPair.Transaction, commandType, commandText, parameterValues); ApplyTransactionTimeout(dbCommand, timeoutInSeconds); IDataReader executeReader = dbCommand.ExecuteReader(); ParameterUtils.CopyParameters(parameterValues, dbCommand); return(executeReader); } catch (Exception) { ConnectionUtils.DisposeConnection(connectionTxPair.Connection, DbProvider); connectionTxPair.Connection = null; throw; } finally { //ConnectionUtils.DisposeConnection(connectionTxPair.Connection, DbProvider); } }
/// <summary> /// 执行SQL,并返回影响的行数 /// </summary> /// <param name="connString">A ConnectionString.</param> /// <param name="commandType">the Sql CommandType.</param> /// <param name="commandText">the execute Sql.</param> /// <param name="timeOutInSeconds">the dbcommand timeout.</param> /// <param name="parameters">the sql parameters.</param> /// <returns>返回受影响的行数.</returns> public int ExecuteNonQuery(string connString, CommandType commandType, string commandText, int timeOutInSeconds, IDbParameters parameters) { AssertUtils.StringNotNullOrEmpty(connString, "connString"); ConnectionTxPair connectionTxPair = GetConnectionTxPair(connString); try { using (IDbCommand dbCommand = DbProvider.CreateCommand()) { PrepareCommand(dbCommand, connectionTxPair.Connection, connectionTxPair.Transaction, CommandType.Text, commandText, parameters); ApplyTransactionTimeout(dbCommand, timeOutInSeconds); int rowCount = dbCommand.ExecuteNonQuery(); ParameterUtils.CopyParameters(parameters, dbCommand); return(rowCount); } } catch (Exception ex) { ConnectionUtils.DisposeConnection(connectionTxPair.Connection, DbProvider); connectionTxPair.Connection = null; throw ex; } finally { ConnectionUtils.DisposeConnection(connectionTxPair.Connection, DbProvider); } }
protected override void DoCleanupAfterCompletion(object transaction) { DbProviderTransactionObject txMgrStateObject = (DbProviderTransactionObject)transaction; if (txMgrStateObject.NewConnectionHolder) { TransactionSynchronizationManager.UnbindResource(DbProvider); } IDbConnection con = txMgrStateObject.ConnectionHolder.Connection; if (log.IsDebugEnabled) { log.Debug("Releasing ADO.NET Connection [" + con + ", " + con.ConnectionString + "] after transaction"); } ConnectionUtils.DisposeConnection(con, DbProvider); //TODO clear out IDbTransaction object? txMgrStateObject.ConnectionHolder.Clear(); }
/// <summary> /// 执行SQL, 返回Dataset /// </summary> /// <param name="connString">the ConnectionString</param> /// <param name="commandType">the sql CommandType.</param> /// <param name="commandText">the execute sql</param> /// <param name="timeoutInSeconds">the dbcommand timeout.</param> /// <param name="parameterValues">the sql parameters</param> /// <returns>return a Dataset</returns> /// <exception cref="ArgumentNullException">如果参数connString为null或空,则抛出此异常</exception> public DataSet ExecuteDataset(string connString, CommandType commandType, string commandText, int timeoutInSeconds, IDbParameters parameterValues) { AssertUtils.StringNotNullOrEmpty(connString, "connString"); ConnectionTxPair connectionTxPair = GetConnectionTxPair(connString); try { using (IDbCommand dbCommand = DbProvider.CreateCommand()) { PrepareCommand(dbCommand, connectionTxPair.Connection, connectionTxPair.Transaction, commandType, commandText, parameterValues); ApplyTransactionTimeout(dbCommand, timeoutInSeconds); IDbDataAdapter dbDataAdapter = DbProvider.CreateDataAdapter(); dbDataAdapter.SelectCommand = dbCommand; var ds = new DataSet(); dbDataAdapter.Fill(ds); ParameterUtils.CopyParameters(parameterValues, dbCommand); return(ds); } } catch (Exception) { ConnectionUtils.DisposeConnection(connectionTxPair.Connection, DbProvider); connectionTxPair.Connection = null; throw; } finally { ConnectionUtils.DisposeConnection(connectionTxPair.Connection, DbProvider); } }
protected void DisposeConnection(IDbConnection conn, IDbProvider dbProvider) { ConnectionUtils.DisposeConnection(conn, dbProvider); }
protected virtual Dictionary <string, DataTable> BuildDatabase(IDictionary <string, Table> tables, SpringBaseDao baseDao, out bool createdDatabase) { createdDatabase = false; ConnectionTxPair connectionTxPairToUse = null; try { connectionTxPairToUse = ConnectionUtils.GetConnectionTxPair(baseDao.DbProvider); ConnectionUtils.DisposeConnection(connectionTxPairToUse.Connection, baseDao.DbProvider); connectionTxPairToUse = null; return(GetCurrentDatabaseTableSchemas(tables, baseDao)); } catch (CannotGetAdoConnectionException) { // Database probably does not exist, so attempt to create it below } finally { if (connectionTxPairToUse != null) { ConnectionUtils.DisposeConnection(connectionTxPairToUse.Connection, baseDao.DbProvider); connectionTxPairToUse = null; } } string saveConnectionString = baseDao.DbProvider.ConnectionString; string databaseName; string newConnectionString = SpringBaseDao.RemoveDatabaseFromConnectionString(baseDao.DbProvider, out databaseName); if (string.IsNullOrEmpty(databaseName)) { throw new ArgumentException(string.Format("Could not locate database name in connection string: \"{0}\"", baseDao.DbProvider.ConnectionString)); } baseDao.DbProvider.ConnectionString = newConnectionString; try { connectionTxPairToUse = ConnectionUtils.GetConnectionTxPair(baseDao.DbProvider); string sql = string.Format("CREATE DATABASE {0}", databaseName); baseDao.AdoTemplate.ExecuteNonQuery(CommandType.Text, sql); createdDatabase = true; } finally { if (connectionTxPairToUse != null) { ConnectionUtils.DisposeConnection(connectionTxPairToUse.Connection, baseDao.DbProvider); connectionTxPairToUse = null; } baseDao.DbProvider.ConnectionString = saveConnectionString; } // Wait for database to be fully created long timeoutTicks = DateTime.Now.Ticks + TimeSpan.FromSeconds(CREATE_DATABASE_WAIT_SECONDS).Ticks; do { try { return(GetCurrentDatabaseTableSchemas(tables, baseDao)); } catch (DataAccessException) { } Thread.Sleep(300); }while (timeoutTicks > DateTime.Now.Ticks); throw new CannotGetAdoConnectionException(); }
/// <summary> /// Closes the connection. /// </summary> /// <param name="connectionAndTransactionHolder">The connection and transaction holder.</param> protected override void CloseConnection(ConnectionAndTransactionHolder connectionAndTransactionHolder) { // Will work for transactional and non-transactional connections. ConnectionUtils.DisposeConnection(connectionAndTransactionHolder.Connection, dbProvider); }