Added DictionaryAdapter.build.
[castle.git] / Services / Transaction / Castle.Services.Transaction / DefaultTransactionManager.cs
blob6e62ad6504e4b07563d7fdd659468bac2f751424
1 // Copyright 2004-2007 Castle Project - http://www.castleproject.org/
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 namespace Castle.Services.Transaction
17 using System;
18 using System.ComponentModel;
19 using Castle.Core.Logging;
21 /// <summary>
22 /// TODO: Ensure this class is thread-safe
23 /// </summary>
24 public class DefaultTransactionManager : MarshalByRefObject, ITransactionManager
26 private static readonly object TransactionCreatedEvent = new object();
27 private static readonly object TransactionCommittedEvent = new object();
28 private static readonly object TransactionRolledbackEvent = new object();
29 private static readonly object TransactionDisposedEvent = new object();
30 private static readonly object ChildTransactionCreatedEvent = new object();
32 private EventHandlerList events = new EventHandlerList();
33 private ILogger logger = NullLogger.Instance;
34 private IActivityManager activityManager;
36 /// <summary>
37 /// Initializes a new instance of the <see cref="DefaultTransactionManager"/> class.
38 /// </summary>
39 public DefaultTransactionManager() : this(new CallContextActivityManager())
43 /// <summary>
44 /// Initializes a new instance of the <see cref="DefaultTransactionManager"/> class.
45 /// </summary>
46 /// <param name="activityManager">The activity manager.</param>
47 public DefaultTransactionManager(IActivityManager activityManager)
49 this.activityManager = activityManager;
52 /// <summary>
53 /// Gets or sets the activity manager.
54 /// </summary>
55 /// <value>The activity manager.</value>
56 public IActivityManager ActivityManager
58 get { return activityManager; }
59 set { activityManager = value; }
62 /// <summary>
63 /// Gets or sets the logger.
64 /// </summary>
65 /// <value>The logger.</value>
66 public ILogger Logger
68 get { return logger; }
69 set { logger = value; }
72 #region MarshalByRefObject
74 public override object InitializeLifetimeService()
76 return null;
79 #endregion
81 #region ITransactionManager Members
83 /// <summary>
84 /// Creates a transaction.
85 /// </summary>
86 /// <param name="transactionMode">The transaction mode.</param>
87 /// <param name="isolationMode">The isolation mode.</param>
88 /// <returns></returns>
89 public virtual ITransaction CreateTransaction(TransactionMode transactionMode, IsolationMode isolationMode)
91 return CreateTransaction(transactionMode, isolationMode, false);
94 /// <summary>
95 /// Creates a transaction.
96 /// </summary>
97 /// <param name="transactionMode">The transaction mode.</param>
98 /// <param name="isolationMode">The isolation mode.</param>
99 /// <param name="distributedTransaction">if set to <c>true</c>, the TM will create a distributed transaction.</param>
100 /// <returns></returns>
101 public virtual ITransaction CreateTransaction(TransactionMode transactionMode, IsolationMode isolationMode, bool distributedTransaction)
103 if (transactionMode == TransactionMode.Unspecified)
105 transactionMode = ObtainDefaultTransactionMode(transactionMode);
108 CheckNotSupportedTransaction(transactionMode);
110 if (CurrentTransaction == null &&
111 (transactionMode == TransactionMode.Supported ||
112 transactionMode == TransactionMode.NotSupported))
114 return null;
117 StandardTransaction transaction = null;
119 if (CurrentTransaction != null)
121 if (transactionMode == TransactionMode.Requires || transactionMode == TransactionMode.Supported)
123 transaction = ((StandardTransaction) CurrentTransaction).CreateChildTransaction();
125 RaiseChildTransactionCreated(transaction, transactionMode, isolationMode, distributedTransaction);
127 logger.DebugFormat("Child Transaction {0} created", transaction.GetHashCode());
131 if (transaction == null)
133 transaction = new StandardTransaction(
134 new TransactionDelegate(RaiseTransactionCommitted),
135 new TransactionDelegate(RaiseTransactionRolledback), transactionMode, isolationMode, distributedTransaction);
137 if (distributedTransaction)
139 transaction.Enlist(new TransactionScopeResourceAdapter(transactionMode, isolationMode));
142 RaiseTransactionCreated(transaction, transactionMode, isolationMode, distributedTransaction);
144 logger.DebugFormat("Transaction {0} created", transaction.GetHashCode());
147 transaction.Logger = logger.CreateChildLogger(transaction.GetType().FullName);
149 activityManager.CurrentActivity.Push(transaction);
151 return transaction;
154 public virtual ITransaction CurrentTransaction
156 get { return activityManager.CurrentActivity.CurrentTransaction; }
159 #region events
161 public event TransactionCreationInfoDelegate TransactionCreated
163 add { events.AddHandler(TransactionCreatedEvent, value); }
164 remove { events.RemoveHandler(TransactionCreatedEvent, value); }
167 public event TransactionCreationInfoDelegate ChildTransactionCreated
169 add { events.AddHandler(ChildTransactionCreatedEvent, value); }
170 remove { events.RemoveHandler(ChildTransactionCreatedEvent, value); }
173 public event TransactionDelegate TransactionCommitted
175 add { events.AddHandler(TransactionCommittedEvent, value); }
176 remove { events.RemoveHandler(TransactionCommittedEvent, value); }
179 public event TransactionDelegate TransactionRolledback
181 add { events.AddHandler(TransactionRolledbackEvent, value); }
182 remove { events.RemoveHandler(TransactionRolledbackEvent, value); }
185 public event TransactionDelegate TransactionDisposed
187 add { events.AddHandler(TransactionDisposedEvent, value); }
188 remove { events.RemoveHandler(TransactionDisposedEvent, value); }
191 protected void RaiseTransactionCreated(ITransaction transaction, TransactionMode transactionMode,
192 IsolationMode isolationMode, bool distributedTransaction)
194 TransactionCreationInfoDelegate eventDelegate = (TransactionCreationInfoDelegate) events[TransactionCreatedEvent];
196 if (eventDelegate != null)
198 eventDelegate(transaction, transactionMode, isolationMode, distributedTransaction);
202 protected void RaiseChildTransactionCreated(ITransaction transaction, TransactionMode transactionMode,
203 IsolationMode isolationMode, bool distributedTransaction)
205 TransactionCreationInfoDelegate eventDelegate =
206 (TransactionCreationInfoDelegate) events[ChildTransactionCreatedEvent];
208 if (eventDelegate != null)
210 eventDelegate(transaction, transactionMode, isolationMode, distributedTransaction);
214 protected void RaiseTransactionDisposed(ITransaction transaction)
216 TransactionDelegate eventDelegate = (TransactionDelegate) events[TransactionDisposedEvent];
218 if (eventDelegate != null)
220 eventDelegate(transaction);
224 protected void RaiseTransactionCommitted(ITransaction transaction)
226 TransactionDelegate eventDelegate = (TransactionDelegate) events[TransactionCommittedEvent];
228 if (eventDelegate != null)
230 eventDelegate(transaction);
234 protected void RaiseTransactionRolledback(ITransaction transaction)
236 TransactionDelegate eventDelegate = (TransactionDelegate) events[TransactionRolledbackEvent];
238 if (eventDelegate != null)
240 eventDelegate(transaction);
244 #endregion
246 public virtual void Dispose(ITransaction transaction)
248 if (transaction == null)
250 throw new ArgumentNullException("transaction", "Tried to dispose a null transaction");
253 if (CurrentTransaction != transaction)
255 throw new ArgumentException("transaction",
256 "Tried to dispose a transaction that is not on the current active transaction");
259 activityManager.CurrentActivity.Pop();
261 if (transaction is IDisposable)
263 (transaction as IDisposable).Dispose();
266 RaiseTransactionDisposed(transaction);
268 logger.DebugFormat("Transaction {0} disposed successfully", transaction.GetHashCode());
271 #endregion
273 protected virtual TransactionMode ObtainDefaultTransactionMode(TransactionMode transactionMode)
275 return TransactionMode.Requires;
278 private void CheckNotSupportedTransaction(TransactionMode transactionMode)
280 if (transactionMode == TransactionMode.NotSupported &&
281 CurrentTransaction != null &&
282 CurrentTransaction.Status == TransactionStatus.Active)
284 String message = "There is a transaction active and the transaction mode " +
285 "explicit says that no transaction is supported for this context";
287 logger.Error(message);
289 throw new TransactionException(message);