예제 #1
0
        /// <summary>
        /// Ends the given <c>HsqlTransaction</c> with either
        /// a commit or rollback.
        /// </summary>
        /// <param name="transaction">The transaction to end.</param>
        /// <param name="commit">
        /// When <c>true</c> then commit; else rollback.
        /// </param>
        internal void EndTransactionInternal(HsqlTransaction transaction, bool commit)
        {
            // sanity check
            if (transaction == null)
            {
                throw new ArgumentNullException("transaction");
            }

            // We need to make a local reference now, so we can tentatively
            // set the instance field to null, but set it back if things go
            // wrong, for instance a transient network partition is in effect
            // that may revert shortly, or an integrity constraint condition
            // that cannot presently be satisfied may also shortly be rectified.
            HsqlTransaction localTransaction = m_transaction;

            // sanity check
            if (transaction != localTransaction)
            {
                throw new InvalidOperationException(
                          "Not issued on this connection: " + transaction); // NOI18N
            }

            // anticipate success
            m_transaction = null;

            try
            {
                // Important:
                //
                // Access session via the Session property, so we puke if,
                // for some reason, this connection is closed or is not in
                // a valid state
                HsqlSession session = Session;

                if (commit)
                {
                    session.Commit();
                }
                else
                {
                    session.Rollback();
                }

                // Important: only if commit/rollback succeeds.
                session.AutoCommit = true;
            }
            catch /*(Exception ex)*/
            {
                // Failure may only be temporary, so don't leave
                // things hanging in limbo.  Instead, provide for
                // the possibility that we might want to retry the
                // operation.
                m_transaction = localTransaction;

                throw;
            }

            // Prevent further use of transaction object:
            localTransaction.DisposeInternal(/*rollback*/ false);
        }
예제 #2
0
        /// <summary>
        /// Begins a new transaction with the specified isolation level.
        /// </summary>
        /// <param name="isolationLevel">
        /// The isolation level.
        /// </param>
        /// <returns>
        /// An object representing the new transaction.
        /// </returns>
        /// <exception cref="HsqlDataSourceException">
        /// When database access error occurs, sql session is closed
        /// or isolation level not supported.
        /// </exception>
        internal HsqlTransaction BeginTransactionInternal(
            IsolationLevel isolationLevel)
        {
            HsqlTransaction transaction = m_transaction;

            if (transaction != null)
            {
                throw new HsqlDataSourceException(
                          "A transaction is already in progress."); // NOI18N
            }

            // Note: property read access includes closed check.
            HsqlSession session = Session;

            if (isolationLevel == IsolationLevel.Unspecified)
            {
                isolationLevel = IsolationLevel.ReadUncommitted;
            }

            // Note: property write access includes validation check
            session.IsolationLevel = isolationLevel;
            session.AutoCommit     = false;

            transaction = new HsqlTransaction(this, isolationLevel);

            m_transaction = transaction;

            return(transaction);
        }
예제 #3
0
        /// <summary>
        /// Closes this connection.
        /// </summary>
        internal void CloseInternal()
        {
            ConnectionState state = m_connectionState;

            if (state == ConnectionState.Closed)
            {
                return;
            }

            HsqlSession session = m_session;

            if (m_session == null)
            {
                // Sanity-Check: Should never happen.
                throw new InvalidOperationException(
                          "HsqlSession is null"); // NOI18N
            }

            // Handle dispose/close while enlisted in a system transaction.

            HsqlTransaction transaction = m_transaction;
            HsqlEnlistment  enlistment  = m_enlistment;

            bool enlisted           = (enlistment != null);
            bool preserveEnlistment = (enlisted && !enlistment.m_disposeConnection);

            if (preserveEnlistment)
            {
#if DEBUG
                // Without this, it is difficult to debug
                // because the m_enlistment's connection
                // ceases to be this one and this connection
                // loses its reference to the enlistment
                // (m_enlistment is set null below).
                m_enlistment_dbg = m_enlistment;
#endif
                // ...then until it ceases to participate in a
                // System.Transactions.Transaction, the enlistment
                // needs a valid local transaction to commit or
                // rollback

                HsqlConnection connection = new HsqlConnection(this);

                connection.m_connectionState = ConnectionState.Open;
                connection.m_session         = session;
                connection.m_enlistment      = enlistment;
                connection.m_transaction     = transaction;

                enlistment.m_dbConnection      = connection;
                enlistment.m_disposeConnection = true;

                if (transaction != null)
                {
                    transaction.m_connection = connection;
                }
            }

            SetStateInternal(ConnectionState.Closed);

            m_session     = null;
            m_transaction = null;
            m_enlistment  = null;
            m_dbMetaData  = null;
            m_settings    = null;

            if (!enlisted)
            {
                // No need to roll back here. This will happen automatically
                // a moment later on the back end in response to the
                // session.Close() call below.
                if (transaction != null)
                {
                    transaction.DisposeInternal(/*rollback*/ false);
                }

                // release the back-end session and any associated resources,
                // such as network sockets, etc.
                session.Close();
            }
        }
        /// <summary>
        /// Ends the given <c>HsqlTransaction</c> with either
        /// a commit or rollback.
        /// </summary>
        /// <param name="transaction">The transaction to end.</param>
        /// <param name="commit">
        /// When <c>true</c> then commit; else rollback.
        /// </param>
        internal void EndTransactionInternal(HsqlTransaction transaction, bool commit)
        {
            // sanity check
            if (transaction == null)
            {
                throw new ArgumentNullException("transaction");
            }

            // We need to make a local reference now, so we can tentatively
            // set the instance field to null, but set it back if things go
            // wrong, for instance a transient network partition is in effect
            // that may revert shortly, or an integrity constraint condition
            // that cannot presently be satisfied may also shortly be rectified.
            HsqlTransaction localTransaction = m_transaction;

            // sanity check
            if (transaction != localTransaction)
            {
                throw new InvalidOperationException(
                    "Not issued on this connection: " + transaction); // NOI18N
            }

            // anticipate success
            m_transaction = null;

            try
            {
                // Important:
                //
                // Access session via the Session property, so we puke if,
                // for some reason, this connection is closed or is not in
                // a valid state
                HsqlSession session = Session;

                if (commit)
                {
                    session.Commit();
                }
                else
                {
                    session.Rollback();
                }

                // Important: only if commit/rollback succeeds.
                session.AutoCommit = true;
            }
            catch /*(Exception ex)*/
            {
                // Failure may only be temporary, so don't leave
                // things hanging in limbo.  Instead, provide for
                // the possibility that we might want to retry the
                // operation.
                m_transaction = localTransaction;

                throw;
            }

            // Prevent further use of transaction object:
            localTransaction.DisposeInternal(/*rollback*/false);
        }
        /// <summary>
        /// Closes this connection.
        /// </summary>
        internal void CloseInternal()
        {
            ConnectionState state = m_connectionState;

            if (state == ConnectionState.Closed)
            {
                return;
            }

            HsqlSession session = m_session;

            if (m_session == null)
            {
                // Sanity-Check: Should never happen.
                throw new InvalidOperationException(
                    "HsqlSession is null"); // NOI18N
            }

            // Handle dispose/close while enlisted in a system transaction.

            HsqlTransaction transaction = m_transaction;
            HsqlEnlistment enlistment = m_enlistment;

            bool enlisted = (enlistment != null);
            bool preserveEnlistment = (enlisted && !enlistment.m_disposeConnection);

            if (preserveEnlistment)
            {
            #if DEBUG
                // Without this, it is difficult to debug
                // because the m_enlistment's connection
                // ceases to be this one and this connection
                // loses its reference to the enlistment
                // (m_enlistment is set null below).
                m_enlistment_dbg = m_enlistment;
            #endif
                // ...then until it ceases to participate in a
                // System.Transactions.Transaction, the enlistment
                // needs a valid local transaction to commit or
                // rollback

                HsqlConnection connection = new HsqlConnection(this);

                connection.m_connectionState = ConnectionState.Open;
                connection.m_session = session;
                connection.m_enlistment = enlistment;
                connection.m_transaction = transaction;

                enlistment.m_dbConnection = connection;
                enlistment.m_disposeConnection = true;

                if (transaction != null)
                {
                    transaction.m_connection = connection;
                }
            }

            SetStateInternal(ConnectionState.Closed);

            m_session = null;
            m_transaction = null;
            m_enlistment = null;
            m_dbMetaData = null;
            m_settings = null;

            if (!enlisted)
            {
                // No need to roll back here. This will happen automatically
                // a moment later on the back end in response to the
                // session.Close() call below.
                if (transaction != null)
                {
                    transaction.DisposeInternal(/*rollback*/false);
                }

                // release the back-end session and any associated resources,
                // such as network sockets, etc.
                session.Close();
            }
        }
        /// <summary>
        /// Begins a new transaction with the specified isolation level.
        /// </summary>
        /// <param name="isolationLevel">
        /// The isolation level.
        /// </param>
        /// <returns>
        /// An object representing the new transaction.
        /// </returns>
        /// <exception cref="HsqlDataSourceException">
        /// When database access error occurs, sql session is closed
        /// or isolation level not supported.
        /// </exception>
        internal HsqlTransaction BeginTransactionInternal(
            IsolationLevel isolationLevel)
        {
            HsqlTransaction transaction = m_transaction;

            if (transaction != null)
            {
                throw new HsqlDataSourceException(
                    "A transaction is already in progress."); // NOI18N
            }

            // Note: property read access includes closed check.
            HsqlSession session = Session;

            if (isolationLevel == IsolationLevel.Unspecified)
            {
                isolationLevel = IsolationLevel.ReadUncommitted;
            }

            // Note: property write access includes validation check
            session.IsolationLevel = isolationLevel;
            session.AutoCommit = false;

            transaction = new HsqlTransaction(this, isolationLevel);

            m_transaction = transaction;

            return transaction;
        }