/// <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> /// 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); }
/// <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; }