/// <summary> /// Gets a "wrapped" connection that will be not be disposed if a transaction is /// active (created by creating a <see cref="TransactionScope"/> instance). The /// connection will be disposed when no transaction is active. /// </summary> /// <returns></returns> protected DatabaseConnectionWrapper GetOpenConnection() { DatabaseConnectionWrapper connection = TransactionScopeConnections.GetConnection(this); //DatabaseConnectionWrapper connection = null; return(connection ?? GetWrappedConnection()); }
/// <summary> /// Returns a connection for the current transaction. This will be an existing <see cref="DbConnection"/> /// instance or a new one if there is a <see cref="TransactionScope"/> active. Otherwise this method /// returns null. /// </summary> /// <param name="db"></param> /// <returns>Either a <see cref="DbConnection"/> instance or null.</returns> public static DatabaseConnectionWrapper GetConnection(Database db) { Transaction currentTransaction = Transaction.Current; if (currentTransaction == null) { return(null); } Dictionary <string, DatabaseConnectionWrapper> connectionList; DatabaseConnectionWrapper connection; lock (transactionConnections) { if (!transactionConnections.TryGetValue(currentTransaction, out connectionList)) { // We don't have a list for this transaction, so create a new one connectionList = new Dictionary <string, DatabaseConnectionWrapper>(); transactionConnections.Add(currentTransaction, connectionList); // We need to know when this previously unknown transaction is completed too currentTransaction.TransactionCompleted += OnTransactionCompleted; } } lock (connectionList) { // Next we'll see if there is already a connection. If not, we'll create a new connection and add it // to the transaction's list of connections. // This collection should only be modified by the thread where the transaction scope was created // while the transaction scope is active. // However there's no documentation to confirm this, so we err on the safe side and lock. if (!connectionList.TryGetValue(db.ConnectionString, out connection)) { // we're betting the cost of acquiring a new finer-grained lock is less than // that of opening a new connection, and besides this allows threads to work in parallel var dbConnection = db.GetNewOpenConnection(); connection = new DatabaseConnectionWrapper(dbConnection); connectionList.Add(db.ConnectionString, connection); } connection.AddRef(); } return(connection); }