private void Dispose(bool disposing) { if (_isDisposed) { return; } if (disposing) { lock (this.SyncRoot) { if (_isDisposed) { return; } DbConnectionScope outerScope = _outerScope; while (outerScope != null && outerScope._isDisposed) { outerScope = outerScope._outerScope; } try { _currentScope = outerScope; } finally { _isDisposed = true; if (_connections.IsValueCreated) { var connections = _connections.Value.Values.ToArray(); _connections.Value.Clear(); foreach (DbConnection connection in connections) { if (connection.State != ConnectionState.Closed) { connection.Dispose(); } } } } } } else { _isDisposed = true; } }
public DbScope(TransactionScopeOption option, IsolationLevel isolationLevel, TimeSpan timeOut) { _disposed = true; if (option != TransactionScopeOption.Suppress) { TransactionOptions tranOp = new TransactionOptions() { IsolationLevel = isolationLevel, Timeout = timeOut }; _tranScope = new TransactionScope(option, tranOp, TransactionScopeAsyncFlowOption.Enabled); _connScope = new DbConnectionScope(option == TransactionScopeOption.RequiresNew? DbConnectionScopeOption.RequiresNew: DbConnectionScopeOption.Required); } else { _tranScope = new TransactionScope(TransactionScopeOption.Suppress, TransactionScopeAsyncFlowOption.Enabled); _connScope = new DbConnectionScope(DbConnectionScopeOption.RequiresNew); } _disposed = false; }
private bool TryGetConnectionByName(DbConnectionScope scope, string connectionName, out DbConnection connection) { connection = null; if (scope.TryGetConnectionByName(connectionName, out connection)) { return(true); } else if (scope.TryGetCompatableScope(out scope)) { if (this.TryGetConnectionByName(scope, connectionName, out connection)) { return(true); } else { return(false); } } return(false); }
public DbConnectionScope(DbConnectionScopeOption option) { _isDisposed = true; // short circuit Dispose until we're properly set up this._transId = CurrentTransactionId; this._option = option; this._outerScope = null; DbConnectionScope outerScope = _currentScope; bool isAllocateOk = (outerScope == null || outerScope._transId != this._transId); if (option == DbConnectionScopeOption.RequiresNew || (option == DbConnectionScopeOption.Required && isAllocateOk)) { // only bother allocating dictionary if we're going to push _connections = new Lazy <ConcurrentDictionary <string, DbConnection> >(() => new ConcurrentDictionary <string, DbConnection>(), true); // Devnote: Order of initial assignment is important in cases of failure! _outerScope = outerScope; _isDisposed = false; _currentScope = this; } }
/// <summary> /// In case of DbConnectionScopeOption equals Required /// it returns outer scope with the same transaction id on the scope /// typically it will be when TransactionScopeOption is Suppress on this scope and the outer scope /// </summary> /// <param name="resultScope"></param> /// <returns></returns> private bool TryGetCompatableScope(out DbConnectionScope resultScope) { resultScope = null; if (this._option == DbConnectionScopeOption.RequiresNew) { return(false); } resultScope = this._outerScope; while (resultScope != null) { //find the outer scope with the same transaction id if (!resultScope._isDisposed && resultScope._transId == this._transId) { break; } else { resultScope = resultScope._outerScope; } } return(resultScope != null); }
public async Task <SqlConnection> GetConnectionByNameAsync(string connectionName) { return(await DbConnectionScope.GetOpenConnectionAsync <SqlConnection>(_dbFactory.Value, connectionName)); }