Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WF / RunTime / Hosting / SharedConnectionWorkflowTransactionService.cs / 1305376 / SharedConnectionWorkflowTransactionService.cs
#pragma warning disable 1634, 1691
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//-----------------------------------------------------------------------------
#region Using directives
using System;
using System.Transactions;
using System.Diagnostics;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Configuration;
using System.Threading;
#endregion
namespace System.Workflow.Runtime.Hosting
{
public class SharedConnectionWorkflowCommitWorkBatchService : WorkflowCommitWorkBatchService
{
private DbResourceAllocator dbResourceAllocator;
private IDictionary transactionConnectionTable;
private object tableSyncObject = new object();
// Saved from constructor input to be used in service start initialization
private NameValueCollection configParameters;
string unvalidatedConnectionString;
private bool _enableRetries = false;
private bool _ignoreCommonEnableRetries = false;
///
/// Enables the adding of this service programmatically.
///
///
///
public SharedConnectionWorkflowCommitWorkBatchService(string connectionString)
{
if (String.IsNullOrEmpty(connectionString))
throw new ArgumentNullException("connectionString", ExecutionStringManager.MissingConnectionString);
this.unvalidatedConnectionString = connectionString;
}
///
/// Enables adding of this service from a config file.
/// Get the connection string from the runtime common parameter section or the particular service parameter section
/// of the configuration file, and instantiate a DbResourceAllocator object.
///
///
///
public SharedConnectionWorkflowCommitWorkBatchService(NameValueCollection parameters)
{
if (parameters == null)
throw new ArgumentNullException("parameters", ExecutionStringManager.MissingParameters);
if (parameters.Count > 0)
{
foreach (string key in parameters.Keys)
{
if (0 == string.Compare("EnableRetries", key, StringComparison.OrdinalIgnoreCase))
{
_enableRetries = bool.Parse(parameters[key]);
_ignoreCommonEnableRetries = true;
}
}
}
this.configParameters = parameters;
}
#region Accessors
internal string ConnectionString
{
get
{
#pragma warning disable 56503
if (this.dbResourceAllocator == null)
{
// Other hosting services may try to get the connection string during their initialization phase
// (in WorkflowRuntimeService.Start) to dectect string mismatch conflict
if (this.Runtime == null)
throw new InvalidOperationException(ExecutionStringManager.WorkflowRuntimeNotStarted);
this.dbResourceAllocator = new DbResourceAllocator(this.Runtime, this.configParameters, this.unvalidatedConnectionString);
}
#pragma warning restore 56503
return this.dbResourceAllocator.ConnectionString;
}
}
public bool EnableRetries
{
get { return _enableRetries; }
set
{
_enableRetries = value;
_ignoreCommonEnableRetries = true;
}
}
#endregion Accessors
#region WorkflowRuntimeService
override protected internal void Start()
{
WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "SharedConnectionWorkflowCommitWorkBatchService: Starting");
this.dbResourceAllocator = new DbResourceAllocator(this.Runtime, this.configParameters, this.unvalidatedConnectionString);
if (this.transactionConnectionTable == null)
this.transactionConnectionTable = new Dictionary();
//
// If we didn't find a local value for enable retries
// check in the common section
if ((!_ignoreCommonEnableRetries) && (null != base.Runtime))
{
NameValueConfigurationCollection commonConfigurationParameters = base.Runtime.CommonParameters;
if (commonConfigurationParameters != null)
{
// Then scan for connection string in the common configuration parameters section
foreach (string key in commonConfigurationParameters.AllKeys)
{
if (string.Compare("EnableRetries", key, StringComparison.OrdinalIgnoreCase) == 0)
{
_enableRetries = bool.Parse(commonConfigurationParameters[key].Value);
break;
}
}
}
}
base.Start();
}
protected override void OnStopped()
{
WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "SharedConnectionWorkflowCommitWorkBatchService: Stopping");
foreach (KeyValuePair kvp in this.transactionConnectionTable)
{
kvp.Value.Dispose();
WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "Removing transaction " + kvp.Key.GetHashCode());
}
this.transactionConnectionTable.Clear();
this.dbResourceAllocator = null;
base.OnStopped();
}
#endregion Public Methods
#region Public Methods
protected internal override void CommitWorkBatch(WorkflowCommitWorkBatchService.CommitWorkBatchCallback commitWorkBatchCallback)
{
//
// Disable retries by default, reset to allow retries below if we own the tx
DbRetry dbRetry = new DbRetry(_enableRetries);
short retryCounter = dbRetry.MaxRetries;
while (true)
{
//
// When using LocalTransaction handle block access to the connection
// in the transaction event handlers until all IPendingWork members have completed
ManualResetEvent handle = new ManualResetEvent(false);
Transaction tx = null;
SharedConnectionInfo connectionInfo = null;
try
{
if (null == Transaction.Current)
{
//
// It's OK to retry here as we own the tx
retryCounter = 0;
//
// Create a local, non promotable transaction that we share with our OOB services
tx = new CommittableTransaction();
connectionInfo = new SharedConnectionInfo(this.dbResourceAllocator, tx, false, handle);
}
else
{
//
// Can't retry as we don't own the tx
// Create a dependent transaction and don't restrict promotion.
tx = Transaction.Current.DependentClone(DependentCloneOption.BlockCommitUntilComplete);
connectionInfo = new SharedConnectionInfo(this.dbResourceAllocator, tx, true, handle);
}
AddToConnectionInfoTable(tx, connectionInfo);
using (TransactionScope ts = new TransactionScope(tx))
{
try
{
commitWorkBatchCallback();
ts.Complete();
}
finally
{
RemoveConnectionFromInfoTable(tx);
//
// Unblock transaction event handlers
handle.Set();
}
}
CommittableTransaction committableTransaction = tx as CommittableTransaction;
if (committableTransaction != null)
committableTransaction.Commit();
DependentTransaction dependentTransaction = tx as DependentTransaction;
if (dependentTransaction != null)
dependentTransaction.Complete();
break;
}
catch (Exception e)
{
tx.Rollback();
WorkflowTrace.Host.TraceEvent(TraceEventType.Error, 0, "SharedConnectionWorkflowCommitWorkBatchService caught exception from commitWorkBatchCallback: " + e.ToString());
if (dbRetry.TryDoRetry(ref retryCounter))
{
WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "SharedConnectionWorkflowCommitWorkBatchService retrying commitWorkBatchCallback (retry attempt " + retryCounter.ToString(System.Globalization.CultureInfo.InvariantCulture) + ")");
continue;
}
else
throw;
}
finally
{
handle.Close();
if (tx != null)
{
tx.Dispose();
}
}
}
}
///
/// Get the SharedConnectionInfo object from the hashtable keyed by the transaction
///
///
///
internal SharedConnectionInfo GetConnectionInfo(Transaction transaction)
{
return LookupConnectionInfoTable(transaction);
}
#endregion Public Methods
#region Private Methods
private void RemoveConnectionFromInfoTable(Transaction transaction)
{
lock (this.tableSyncObject)
{
SharedConnectionInfo connectionInfo;
WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "TransactionCompleted " + transaction.GetHashCode());
if (transactionConnectionTable.TryGetValue(transaction, out connectionInfo))
{
connectionInfo.Dispose();
this.transactionConnectionTable.Remove(transaction);
}
else
{
WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "TransactionCompleted " + transaction.GetHashCode() +
" not found in table of count " + this.transactionConnectionTable.Count);
}
}
}
private void AddToConnectionInfoTable(Transaction transaction, SharedConnectionInfo connectionInfo)
{
lock (this.tableSyncObject)
{
this.transactionConnectionTable.Add(transaction, connectionInfo);
WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "AddToConnectionInfoTable " + transaction.GetHashCode() +
" in table of count " + this.transactionConnectionTable.Count);
}
}
private SharedConnectionInfo LookupConnectionInfoTable(Transaction transaction)
{
lock (this.tableSyncObject)
{
return transactionConnectionTable[transaction];
}
}
#endregion Private Methods
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- PackWebRequestFactory.cs
- cookiecollection.cs
- InfiniteIntConverter.cs
- WebPartUserCapability.cs
- OleDbParameter.cs
- CatalogZone.cs
- RowSpanVector.cs
- CodePrimitiveExpression.cs
- SynchronousReceiveBehavior.cs
- CompiledQueryCacheKey.cs
- RoleExceptions.cs
- TabletDeviceInfo.cs
- TextElementEnumerator.cs
- Parallel.cs
- MetadataItemCollectionFactory.cs
- NominalTypeEliminator.cs
- XmlBinaryReaderSession.cs
- ImageField.cs
- BaseServiceProvider.cs
- AggregateNode.cs
- XmlImplementation.cs
- PriorityQueue.cs
- DataGridToolTip.cs
- MediaPlayer.cs
- returneventsaver.cs
- TextRangeEditTables.cs
- RenderingBiasValidation.cs
- PenContext.cs
- GridItemProviderWrapper.cs
- UserMapPath.cs
- TypeBuilderInstantiation.cs
- LocationFactory.cs
- DateTimeSerializationSection.cs
- ObjectDataSourceDisposingEventArgs.cs
- WindowInteractionStateTracker.cs
- HttpException.cs
- AutomationIdentifierGuids.cs
- Composition.cs
- WindowsIdentity.cs
- AssociationType.cs
- ToolboxItemCollection.cs
- Overlapped.cs
- ThreadStaticAttribute.cs
- TemplateInstanceAttribute.cs
- Utils.cs
- UnlockInstanceCommand.cs
- BaseProcessor.cs
- ExeConfigurationFileMap.cs
- TextPointerBase.cs
- ClassValidator.cs
- LoginCancelEventArgs.cs
- CodeCatchClause.cs
- ContextProperty.cs
- XamlToRtfParser.cs
- SurrogateEncoder.cs
- CustomAttribute.cs
- SupportsEventValidationAttribute.cs
- ResourceAssociationTypeEnd.cs
- SqlDataReader.cs
- TransactionManager.cs
- DataGridViewCellFormattingEventArgs.cs
- EventMap.cs
- VisualStyleInformation.cs
- FixedPageStructure.cs
- HtmlInputRadioButton.cs
- ProxyWebPartManager.cs
- TextEditorCopyPaste.cs
- SqlFactory.cs
- SelectionPattern.cs
- LazyInitializer.cs
- ReaderWriterLockWrapper.cs
- AttributeEmitter.cs
- NotSupportedException.cs
- GridViewCellAutomationPeer.cs
- SqlDataSourceView.cs
- StatusBar.cs
- DependencyStoreSurrogate.cs
- XmlWellformedWriter.cs
- InputLangChangeRequestEvent.cs
- HandledEventArgs.cs
- ReadOnlyDataSource.cs
- BamlRecordWriter.cs
- XmlSchemaAppInfo.cs
- DataGridViewSelectedCellsAccessibleObject.cs
- figurelength.cs
- SystemWebCachingSectionGroup.cs
- TextEmbeddedObject.cs
- IPEndPointCollection.cs
- StreamGeometry.cs
- HandlerBase.cs
- RepeaterItem.cs
- CharStorage.cs
- GridViewRowEventArgs.cs
- DateTimeSerializationSection.cs
- RegexCode.cs
- Rotation3DAnimationBase.cs
- ClassGenerator.cs
- Converter.cs
- Drawing.cs
- SourceItem.cs