internal PersistenceDBAccessor(DbResourceAllocator dbResourceAllocator, Transaction transaction, WorkflowCommitWorkBatchService transactionService) { this.dbResourceAllocator = dbResourceAllocator; this.localTransaction = DbResourceAllocator.GetLocalTransaction(transactionService, transaction); this.connection = this.dbResourceAllocator.GetEnlistedConnection(transactionService, transaction, out this.needToCloseConnection); this.dbRetry = new DbRetry(false); }
internal void DetectSharedConnectionConflict(WorkflowCommitWorkBatchService transactionService) { SharedConnectionWorkflowCommitWorkBatchService service = transactionService as SharedConnectionWorkflowCommitWorkBatchService; if ((service != null) && (string.Compare(service.ConnectionString, this.connString, StringComparison.Ordinal) != 0)) { throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, ExecutionStringManager.SharedConnectionStringSpecificationConflict, new object[] { this.connString, service.ConnectionString })); } }
internal void DetectSharedConnectionConflict(WorkflowCommitWorkBatchService transactionService) { SharedConnectionWorkflowCommitWorkBatchService service = transactionService as SharedConnectionWorkflowCommitWorkBatchService; if ((service != null) && (string.Compare(service.ConnectionString, this.connString, StringComparison.Ordinal) != 0)) { throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, ExecutionStringManager.SharedConnectionStringSpecificationConflict, new object[] { this.connString, service.ConnectionString })); } }
internal static DbTransaction GetLocalTransaction(WorkflowCommitWorkBatchService txSvc, Transaction transaction) { DbTransaction dBTransaction = null; SharedConnectionInfo connectionInfo = GetConnectionInfo(txSvc, transaction); if (connectionInfo != null) { dBTransaction = connectionInfo.DBTransaction; } return(dBTransaction); }
private static SharedConnectionInfo GetConnectionInfo(WorkflowCommitWorkBatchService txSvc, Transaction transaction) { SharedConnectionInfo connectionInfo = null; SharedConnectionWorkflowCommitWorkBatchService service = txSvc as SharedConnectionWorkflowCommitWorkBatchService; if (service != null) { connectionInfo = service.GetConnectionInfo(transaction); if (connectionInfo == null) { throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, ExecutionStringManager.InvalidTransaction, new object[0])); } } return connectionInfo; }
private static SharedConnectionInfo GetConnectionInfo(WorkflowCommitWorkBatchService txSvc, Transaction transaction) { SharedConnectionInfo connectionInfo = null; SharedConnectionWorkflowCommitWorkBatchService service = txSvc as SharedConnectionWorkflowCommitWorkBatchService; if (service != null) { connectionInfo = service.GetConnectionInfo(transaction); if (connectionInfo == null) { throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, ExecutionStringManager.InvalidTransaction, new object[0])); } } return(connectionInfo); }
internal DbConnection GetEnlistedConnection(WorkflowCommitWorkBatchService txSvc, Transaction transaction, out bool isNewConnection) { DbConnection dBConnection; SharedConnectionInfo connectionInfo = GetConnectionInfo(txSvc, transaction); if (connectionInfo != null) { dBConnection = connectionInfo.DBConnection; isNewConnection = false; return dBConnection; } dBConnection = this.OpenNewConnection(); dBConnection.EnlistTransaction(transaction); isNewConnection = true; return dBConnection; }
/// <summary> /// DB access done under a transaction and uses a connection enlisted to this transaction. /// </summary> /// <param name="dbResourceAllocator">Helper to get database connection/command/store procedure parameters/etc</param> /// <param name="transaction">The transaction to do this work under</param> internal PersistenceDBAccessor( DbResourceAllocator dbResourceAllocator, System.Transactions.Transaction transaction, WorkflowCommitWorkBatchService transactionService) { this.dbResourceAllocator = dbResourceAllocator; this.localTransaction = DbResourceAllocator.GetLocalTransaction( transactionService, transaction); // Get a connection enlisted to this transaction, may or may not need to be freed depending on // if the transaction does connection sharing this.connection = this.dbResourceAllocator.GetEnlistedConnection( transactionService, transaction, out needToCloseConnection); // // No retries for external transactions this.dbRetry = new DbRetry(false); }
internal DbConnection GetEnlistedConnection(WorkflowCommitWorkBatchService txSvc, Transaction transaction, out bool isNewConnection) { DbConnection dBConnection; SharedConnectionInfo connectionInfo = GetConnectionInfo(txSvc, transaction); if (connectionInfo != null) { dBConnection = connectionInfo.DBConnection; isNewConnection = false; return(dBConnection); } dBConnection = this.OpenNewConnection(); dBConnection.EnlistTransaction(transaction); isNewConnection = true; return(dBConnection); }
/* * private void SetLocalProvider(string connectionString) * { * // Assume caller already validated the connection string * MatchCollection providers = Regex.Matches(connectionString, @"(^|;)\s*provider\s*=[^;$]*(;|$)", RegexOptions.IgnoreCase); * * // Cannot use DbConnectionStringBuilder because it selects the last provider, not the first one, by itself. * // A legal Sql connection string allows for multiple provider specification and * // selects the first provider * if (providers.Count > 0) * { * // Check if the first one matches "sqloledb" or "sqloledb.<digit>" * if (Regex.IsMatch(providers[0].Value, @"provider\s*=\s*sqloledb(\.\d+)?\s*(;|$)", RegexOptions.IgnoreCase)) * { * this.localProvider = Provider.OleDB; * } * else * { * // We don't support other providers * throw new ArgumentException(String.Format(CultureInfo.CurrentCulture,ExecutionStringManager.UnsupportedSqlProvider, providers[0].Value)); * } * } * else * { * // SqlClient provider requires no provider keyword specified in connection string * this.localProvider = Provider.SqlClient; * } * } */ private static SharedConnectionInfo GetConnectionInfo(WorkflowCommitWorkBatchService txSvc, Transaction transaction) { SharedConnectionInfo connectionInfo = null; SharedConnectionWorkflowCommitWorkBatchService scTxSvc = txSvc as SharedConnectionWorkflowCommitWorkBatchService; if (scTxSvc != null) { connectionInfo = scTxSvc.GetConnectionInfo(transaction); // The transaction service can't find entry if the transaction has been completed. // be sure to propate the error so durable services can cast to appropriate exception if (connectionInfo == null) { throw new ArgumentException( String.Format(CultureInfo.CurrentCulture, ExecutionStringManager.InvalidTransaction)); } } return(connectionInfo); }
protected internal override void Start() { WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "SqlWorkflowPersistenceService({1}): Starting, LoadInternalSeconds={0}", new object[] { this.loadingInterval.TotalSeconds, this._serviceInstanceId.ToString() }); this._dbResourceAllocator = new DbResourceAllocator(base.Runtime, this.configParameters, this.unvalidatedConnectionString); this._transactionService = base.Runtime.GetService <WorkflowCommitWorkBatchService>(); this._dbResourceAllocator.DetectSharedConnectionConflict(this._transactionService); if (!this._ignoreCommonEnableRetries && (base.Runtime != null)) { NameValueConfigurationCollection commonParameters = base.Runtime.CommonParameters; if (commonParameters != null) { foreach (string str in commonParameters.AllKeys) { if (string.Compare("EnableRetries", str, StringComparison.OrdinalIgnoreCase) == 0) { this._enableRetries = bool.Parse(commonParameters[str].Value); break; } } } } base.Start(); }
protected internal override void CommitWorkBatch(WorkflowCommitWorkBatchService.CommitWorkBatchCallback commitWorkBatchCallback) { DbRetry retry = new DbRetry(this._enableRetries); short retryCount = 0; Label_000E: if (null != Transaction.Current) { retryCount = retry.MaxRetries; } try { base.CommitWorkBatch(commitWorkBatchCallback); } catch (Exception exception) { WorkflowTrace.Host.TraceEvent(TraceEventType.Error, 0, "DefaultWorkflowCommitWorkBatchService caught exception from commitWorkBatchCallback: " + exception.ToString()); if (!retry.TryDoRetry(ref retryCount)) { throw; } WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "DefaultWorkflowCommitWorkBatchService retrying commitWorkBatchCallback (retry attempt " + retryCount.ToString(CultureInfo.InvariantCulture) + ")"); goto Label_000E; } }
/// <summary> /// Gets a connection enlisted to the transaction. /// If the transaction already has a connection attached to it, we return that, /// otherwise we create a new connection and enlist to the transaction /// </summary> /// <param name="transaction"></param> /// <param name="isNewConnection">output if we created a connection</param> /// <returns></returns> internal DbConnection GetEnlistedConnection(WorkflowCommitWorkBatchService txSvc, Transaction transaction, out bool isNewConnection) { DbConnection connection; SharedConnectionInfo connectionInfo = GetConnectionInfo(txSvc, transaction); if (connectionInfo != null) { connection = connectionInfo.DBConnection; Debug.Assert((connection != null), "null connection"); Debug.Assert((connection.State == System.Data.ConnectionState.Open), "Invalid connection state " + connection.State + " for connection " + connection); isNewConnection = false; } else { connection = this.OpenNewConnection(); connection.EnlistTransaction(transaction); isNewConnection = true; } return(connection); }
/* private void SetLocalProvider(string connectionString) { // Assume caller already validated the connection string MatchCollection providers = Regex.Matches(connectionString, @"(^|;)\s*provider\s*=[^;$]*(;|$)", RegexOptions.IgnoreCase); // Cannot use DbConnectionStringBuilder because it selects the last provider, not the first one, by itself. // A legal Sql connection string allows for multiple provider specification and // selects the first provider if (providers.Count > 0) { // Check if the first one matches "sqloledb" or "sqloledb.<digit>" if (Regex.IsMatch(providers[0].Value, @"provider\s*=\s*sqloledb(\.\d+)?\s*(;|$)", RegexOptions.IgnoreCase)) { this.localProvider = Provider.OleDB; } else { // We don't support other providers throw new ArgumentException(String.Format(CultureInfo.CurrentCulture,ExecutionStringManager.UnsupportedSqlProvider, providers[0].Value)); } } else { // SqlClient provider requires no provider keyword specified in connection string this.localProvider = Provider.SqlClient; } } */ private static SharedConnectionInfo GetConnectionInfo(WorkflowCommitWorkBatchService txSvc, Transaction transaction) { SharedConnectionInfo connectionInfo = null; SharedConnectionWorkflowCommitWorkBatchService scTxSvc = txSvc as SharedConnectionWorkflowCommitWorkBatchService; if (scTxSvc != null) { connectionInfo = scTxSvc.GetConnectionInfo(transaction); // The transaction service can't find entry if the transaction has been completed. // be sure to propate the error so durable services can cast to appropriate exception if (connectionInfo == null) throw new ArgumentException( String.Format(CultureInfo.CurrentCulture, ExecutionStringManager.InvalidTransaction)); } return connectionInfo; }
internal static DbTransaction GetLocalTransaction(WorkflowCommitWorkBatchService txSvc, Transaction transaction) { DbTransaction localTransaction = null; SharedConnectionInfo connectionInfo = GetConnectionInfo(txSvc, transaction); if (connectionInfo != null) localTransaction = connectionInfo.DBTransaction; return localTransaction; }
/// <summary> /// Gets a connection enlisted to the transaction. /// If the transaction already has a connection attached to it, we return that, /// otherwise we create a new connection and enlist to the transaction /// </summary> /// <param name="transaction"></param> /// <param name="isNewConnection">output if we created a connection</param> /// <returns></returns> internal DbConnection GetEnlistedConnection(WorkflowCommitWorkBatchService txSvc, Transaction transaction, out bool isNewConnection) { DbConnection connection; SharedConnectionInfo connectionInfo = GetConnectionInfo(txSvc, transaction); if (connectionInfo != null) { connection = connectionInfo.DBConnection; Debug.Assert((connection != null), "null connection"); Debug.Assert((connection.State == System.Data.ConnectionState.Open), "Invalid connection state " + connection.State + " for connection " + connection); isNewConnection = false; } else { connection = this.OpenNewConnection(); connection.EnlistTransaction(transaction); isNewConnection = true; } return connection; }
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(); } } } }
internal PersistenceDBAccessor(DbResourceAllocator dbResourceAllocator, Transaction transaction, WorkflowCommitWorkBatchService transactionService) { this.dbResourceAllocator = dbResourceAllocator; this.localTransaction = DbResourceAllocator.GetLocalTransaction(transactionService, transaction); this.connection = this.dbResourceAllocator.GetEnlistedConnection(transactionService, transaction, out this.needToCloseConnection); this.dbRetry = new DbRetry(false); }
protected internal override void Start() { WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "SqlWorkflowPersistenceService({1}): Starting, LoadInternalSeconds={0}", new object[] { this.loadingInterval.TotalSeconds, this._serviceInstanceId.ToString() }); this._dbResourceAllocator = new DbResourceAllocator(base.Runtime, this.configParameters, this.unvalidatedConnectionString); this._transactionService = base.Runtime.GetService<WorkflowCommitWorkBatchService>(); this._dbResourceAllocator.DetectSharedConnectionConflict(this._transactionService); if (!this._ignoreCommonEnableRetries && (base.Runtime != null)) { NameValueConfigurationCollection commonParameters = base.Runtime.CommonParameters; if (commonParameters != null) { foreach (string str in commonParameters.AllKeys) { if (string.Compare("EnableRetries", str, StringComparison.OrdinalIgnoreCase) == 0) { this._enableRetries = bool.Parse(commonParameters[str].Value); break; } } } } base.Start(); }
override protected internal void Start() { WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "SqlWorkflowPersistenceService({1}): Starting, LoadInternalSeconds={0}", loadingInterval.TotalSeconds, _serviceInstanceId.ToString()); _dbResourceAllocator = new DbResourceAllocator(this.Runtime, this.configParameters, this.unvalidatedConnectionString); // Check connection string mismatch if using SharedConnectionWorkflowTransactionService _transactionService = Runtime.GetService<WorkflowCommitWorkBatchService>(); _dbResourceAllocator.DetectSharedConnectionConflict(_transactionService); // // 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(EnableRetriesToken, key, StringComparison.OrdinalIgnoreCase) == 0) { _enableRetries = bool.Parse(commonConfigurationParameters[key].Value); break; } } } } base.Start(); }
protected internal override void CommitWorkBatch(WorkflowCommitWorkBatchService.CommitWorkBatchCallback commitWorkBatchCallback) { ManualResetEvent event2; DbRetry retry = new DbRetry(this._enableRetries); short maxRetries = retry.MaxRetries; Label_0013: event2 = new ManualResetEvent(false); Transaction transaction = null; SharedConnectionInfo connectionInfo = null; try { if (null == Transaction.Current) { maxRetries = 0; transaction = new CommittableTransaction(); connectionInfo = new SharedConnectionInfo(this.dbResourceAllocator, transaction, false, event2); } else { transaction = Transaction.Current.DependentClone(DependentCloneOption.BlockCommitUntilComplete); connectionInfo = new SharedConnectionInfo(this.dbResourceAllocator, transaction, true, event2); } this.AddToConnectionInfoTable(transaction, connectionInfo); using (TransactionScope scope = new TransactionScope(transaction)) { try { commitWorkBatchCallback(); scope.Complete(); } finally { this.RemoveConnectionFromInfoTable(transaction); event2.Set(); } } CommittableTransaction transaction2 = transaction as CommittableTransaction; if (transaction2 != null) { transaction2.Commit(); } DependentTransaction transaction3 = transaction as DependentTransaction; if (transaction3 != null) { transaction3.Complete(); } } catch (Exception exception) { transaction.Rollback(); WorkflowTrace.Host.TraceEvent(TraceEventType.Error, 0, "SharedConnectionWorkflowCommitWorkBatchService caught exception from commitWorkBatchCallback: " + exception.ToString()); if (!retry.TryDoRetry(ref maxRetries)) { throw; } WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "SharedConnectionWorkflowCommitWorkBatchService retrying commitWorkBatchCallback (retry attempt " + maxRetries.ToString(CultureInfo.InvariantCulture) + ")"); goto Label_0013; } finally { event2.Close(); if (transaction != null) { transaction.Dispose(); } } }