1 // NpgsqlResourceManager.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.
26 using System
.Collections
.Generic
;
27 using System
.Transactions
;
31 internal interface INpgsqlResourceManager
33 void Enlist(INpgsqlTransactionCallbacks transactionCallbacks
, byte[] txToken
);
34 byte[] Promote(INpgsqlTransactionCallbacks transactionCallbacks
);
35 void CommitWork(string txName
);
36 void RollbackWork(string txName
);
39 internal class NpgsqlResourceManager
: MarshalByRefObject
, INpgsqlResourceManager
41 private readonly Dictionary
<string, CommittableTransaction
> _transactions
= new Dictionary
<string, CommittableTransaction
>();
43 #region INpgsqlTransactionManager Members
45 public byte[] Promote(INpgsqlTransactionCallbacks callbacks
)
47 CommittableTransaction tx
= new CommittableTransaction();
48 DurableResourceManager rm
= new DurableResourceManager(this, callbacks
, tx
);
49 byte[] token
= TransactionInterop
.GetTransmitterPropagationToken(tx
);
50 _transactions
.Add(rm
.TxName
, tx
);
55 public void Enlist(INpgsqlTransactionCallbacks callbacks
, byte[] txToken
)
57 DurableResourceManager rm
= new DurableResourceManager(this, callbacks
);
61 public void CommitWork(string txName
)
63 CommittableTransaction tx
;
64 if (_transactions
.TryGetValue(txName
, out tx
))
67 _transactions
.Remove(txName
);
71 public void RollbackWork(string txName
)
73 CommittableTransaction tx
;
74 if (_transactions
.TryGetValue(txName
, out tx
))
76 _transactions
.Remove(txName
);
77 // you can fail to commit,
78 // but you're not getting out
79 // of a rollback. Remove from list first.
86 private class DurableResourceManager
: IEnlistmentNotification
88 private CommittableTransaction _tx
;
89 private NpgsqlResourceManager _rm
;
90 private readonly INpgsqlTransactionCallbacks _callbacks
;
91 private string _txName
;
93 public DurableResourceManager(NpgsqlResourceManager rm
, INpgsqlTransactionCallbacks callbacks
)
94 : this(rm
, callbacks
, null)
98 public DurableResourceManager(NpgsqlResourceManager rm
, INpgsqlTransactionCallbacks callbacks
,
99 CommittableTransaction tx
)
103 _callbacks
= callbacks
;
110 // delay initialize since callback methods may be expensive
113 _txName
= _callbacks
.GetName();
119 #region IEnlistmentNotification Members
121 public void Commit(Enlistment enlistment
)
123 _callbacks
.CommitTransaction();
124 // TODO: remove record of prepared
126 _callbacks
.Dispose();
129 public void InDoubt(Enlistment enlistment
)
131 // not going to happen when enlisted durably
132 throw new NotImplementedException();
135 public void Prepare(PreparingEnlistment preparingEnlistment
)
137 _callbacks
.PrepareTransaction();
138 // TODO: record prepared
139 preparingEnlistment
.Prepared();
142 public void Rollback(Enlistment enlistment
)
144 _callbacks
.RollbackTransaction();
145 // TODO: remove record of prepared
147 _callbacks
.Dispose();
152 private static readonly Guid rmGuid
= new Guid("9e1b6d2d-8cdb-40ce-ac37-edfe5f880716");
154 public Transaction
Enlist(byte[] token
)
156 return Enlist(TransactionInterop
.GetTransactionFromTransmitterPropagationToken(token
));
159 public Transaction
Enlist(Transaction tx
)
161 tx
.EnlistDurable(rmGuid
, this, EnlistmentOptions
.None
);