// created on 17/11/2002 at 19:04 // Npgsql.NpgsqlTransaction.cs // // Author: // Francisco Jr. (fxjrlists@yahoo.com.br) // // Copyright (C) 2002 The Npgsql Development Team // npgsql-general@gborg.postgresql.org // http://gborg.postgresql.org/project/npgsql/projdisplay.php // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA using System; using System.Text; using System.Resources; using System.Data; namespace Npgsql { /// /// Represents a transaction to be made in a PostgreSQL database. This class cannot be inherited. /// public sealed class NpgsqlTransaction : MarshalByRefObject, IDbTransaction { private static readonly String CLASSNAME = "NpgsqlTransaction"; private static ResourceManager resman = new ResourceManager(typeof(NpgsqlTransaction)); private NpgsqlConnection _conn = null; private IsolationLevel _isolation = IsolationLevel.ReadCommitted; private bool _disposed = false; internal NpgsqlTransaction(NpgsqlConnection conn) : this(conn, IsolationLevel.ReadCommitted) {} internal NpgsqlTransaction(NpgsqlConnection conn, IsolationLevel isolation) { resman = new System.Resources.ResourceManager(this.GetType()); NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, CLASSNAME); if ((isolation != IsolationLevel.ReadCommitted) && (isolation != IsolationLevel.Serializable)) throw new ArgumentOutOfRangeException(resman.GetString("Exception_UnsopportedIsolationLevel"), "isolation"); _conn = conn; _isolation = isolation; StringBuilder commandText = new StringBuilder("SET TRANSACTION ISOLATION LEVEL "); if (isolation == IsolationLevel.ReadCommitted) commandText.Append("READ COMMITTED"); else commandText.Append("SERIALIZABLE"); commandText.Append("; BEGIN"); NpgsqlCommand command = new NpgsqlCommand(commandText.ToString(), conn.Connector); command.ExecuteNonQuery(); _conn.Connector.Transaction = this; } /// /// Gets the NpgsqlConnection /// object associated with the transaction, or a null reference if the /// transaction is no longer valid. /// /// The NpgsqlConnection /// object associated with the transaction. public NpgsqlConnection Connection { get { return _conn; } } IDbConnection IDbTransaction.Connection { get { return Connection; } } /// /// Specifies the IsolationLevel for this transaction. /// /// The IsolationLevel for this transaction. /// The default is ReadCommitted. public IsolationLevel IsolationLevel { get { if (_conn == null) { throw new InvalidOperationException(resman.GetString("Exception_NoTransaction")); } return _isolation; } } /// /// Releases the unmanaged resources used by the /// NpgsqlTransaction /// and optionally releases the managed resources. /// public void Dispose() { GC.SuppressFinalize(this); this.Dispose(true); } private void Dispose(Boolean disposing) { if(disposing && this._conn != null) { if (_conn.Connector.Transaction != null) this.Rollback(); this._disposed = true; } } /// /// Commits the database transaction. /// public void Commit() { CheckDisposed(); if (_conn == null) { throw new InvalidOperationException(resman.GetString("Exception_NoTransaction")); } NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Commit"); NpgsqlCommand command = new NpgsqlCommand("COMMIT", _conn.Connector); command.ExecuteNonQuery(); _conn.Connector.Transaction = null; _conn = null; } /// /// Rolls back a transaction from a pending state. /// public void Rollback() { CheckDisposed(); if (_conn == null) { throw new InvalidOperationException(resman.GetString("Exception_NoTransaction")); } NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Rollback"); NpgsqlCommand command = new NpgsqlCommand("ROLLBACK", _conn.Connector); command.ExecuteNonQuery(); _conn.Connector.Transaction = null; _conn = null; } /// /// Cancel the transaction without telling the backend about it. This is /// used to make the transaction go away when closing a connection. /// internal void Cancel() { CheckDisposed(); if (_conn != null) { _conn.Connector.Transaction = null; _conn = null; } } internal bool Disposed{ get { return _disposed; } } internal void CheckDisposed() { if (_disposed) throw new ObjectDisposedException(CLASSNAME); } ~NpgsqlTransaction() { Dispose(false); } } }