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;