1 // NpgsqlTransactionCallbacks.cs
4 // Josh Cooley <jbnpgsql@tuxinthebox.net>
6 // Copyright (C) 2007, The Npgsql Development Team
8 // Permission to use, copy, modify, and distribute this software and its
9 // documentation for any purpose, without fee, and without a written
10 // agreement is hereby granted, provided that the above copyright notice
11 // and this paragraph and the following two paragraphs appear in all copies.
13 // IN NO EVENT SHALL THE NPGSQL DEVELOPMENT TEAM BE LIABLE TO ANY PARTY
14 // FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,
15 // INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
16 // DOCUMENTATION, EVEN IF THE NPGSQL DEVELOPMENT TEAM HAS BEEN ADVISED OF
17 // THE POSSIBILITY OF SUCH DAMAGE.
19 // THE NPGSQL DEVELOPMENT TEAM SPECIFICALLY DISCLAIMS ANY WARRANTIES,
20 // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
21 // AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
22 // ON AN "AS IS" BASIS, AND THE NPGSQL DEVELOPMENT TEAM HAS NO OBLIGATIONS
23 // TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
30 internal interface INpgsqlTransactionCallbacks : IDisposable
33 void PrepareTransaction();
34 void CommitTransaction();
35 void RollbackTransaction();
38 internal class NpgsqlTransactionCallbacks : MarshalByRefObject, INpgsqlTransactionCallbacks
40 private NpgsqlConnection _connection;
41 private readonly string _connectionString;
42 private bool _closeConnectionRequired;
43 private bool _prepared;
44 private readonly string _txName = Guid.NewGuid().ToString();
46 private static readonly String CLASSNAME = "NpgsqlTransactionCallbacks";
48 public NpgsqlTransactionCallbacks(NpgsqlConnection connection)
50 _connection = connection;
51 _connectionString = _connection.ConnectionString;
52 _connection.Disposed += new EventHandler(_connection_Disposed);
55 private void _connection_Disposed(object sender, EventArgs e)
57 // TODO: what happens if this is called from another thread?
58 // connections should not be shared across threads while in a transaction
59 _connection.Disposed -= new EventHandler(_connection_Disposed);
63 private NpgsqlConnection GetConnection()
65 if (_connection == null || (_connection.FullState & ConnectionState.Open) != ConnectionState.Open)
67 _connection = new NpgsqlConnection(_connectionString);
69 _closeConnectionRequired = true;
78 #region INpgsqlTransactionCallbacks Members
80 public string GetName()
85 public void CommitTransaction()
87 NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "CommitTransaction");
88 NpgsqlConnection connection = GetConnection();
89 NpgsqlCommand command = null;
92 command = new NpgsqlCommand(string.Format("COMMIT PREPARED '{0}'", _txName), connection);
96 command = new NpgsqlCommand("COMMIT", connection);
98 command.ExecuteBlind();
101 public void PrepareTransaction()
105 NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "PrepareTransaction");
106 NpgsqlConnection connection = GetConnection();
107 NpgsqlCommand command = new NpgsqlCommand(string.Format("PREPARE TRANSACTION '{0}'", _txName), connection);
108 command.ExecuteBlind();
113 public void RollbackTransaction()
115 NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "RollbackTransaction");
116 NpgsqlConnection connection = GetConnection();
117 NpgsqlCommand command = null;
120 command = new NpgsqlCommand(string.Format("ROLLBACK PREPARED '{0}'", _txName), connection);
124 command = new NpgsqlCommand("ROLLBACK", connection);
126 command.ExecuteBlind();
131 #region IDisposable Members
133 public void Dispose()
135 if (_closeConnectionRequired)
139 _closeConnectionRequired = false;