コード例 #1
0
        /// <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(CustomDatabase 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);
        }
コード例 #2
0
 /// <summary>
 /// Create a new <see cref='RefCountingDataReader'/> that wraps
 /// the given <paramref name="innerReader"/> and properly
 /// cleans the refcount on the given <paramref name="connection"/>
 /// when done.
 /// </summary>
 /// <param name="connection">Connection to close.</param>
 /// <param name="innerReader">Reader to do the actual work.</param>
 public RefCountingDataReader(DatabaseConnectionWrapper connection, IDataReader innerReader)
     : base(innerReader)
 {
     _connectionWrapper = connection;
     _connectionWrapper.AddRef();
 }
コード例 #3
0
 protected virtual IDataReader CreateWrappedReader(DatabaseConnectionWrapper connection, IDataReader innerReader)
 {
     return(new RefCountingDataReader(connection, innerReader));
 }