private AdapterTransaction CreateTransaction(string instanceId) { try { WarehouseAdapterEndPoint endPoint = CreateEndPoint(instanceId); IDbTransaction transaction = endPoint.Connection.BeginTransaction(IsolationLevel.ReadCommitted); AdapterTransaction adapterTransaction = new AdapterTransaction(instanceId, transaction, endPoint); adapterTransaction.State = TransactionState.Started; return(adapterTransaction); } catch (InvalidOperationException ex) { throw new AdapterException("Failed to start transaction for Warehouse instance: \"" + instanceId + "\".", ex); } catch (OracleException ex) { throw new AdapterException("Failed to start transaction for Warehouse instance: \"" + instanceId + "\".", ex); } catch (DbException ex) { throw new AdapterException("Failed to start transaction for Warehouse instance: \"" + instanceId + "\".", ex); } }
/// <summary> /// Starts a transaction for this adapter /// </summary> /// <param name="msg">The message that is to be enlisted in the transaction</param> /// <returns>The transaction in which the message should be enlisted</returns> public AdapterTransaction StartTransaction(MultiPartMessage msg) { if (msg == null) { throw new ArgumentNullException("msg"); } Uri sendUri = msg.Metadata.Read("SendUri") as Uri; //The warehouse instance is the host part of the send uri string instanceId = sendUri.Host; //Check if a transaction is already enlisted in the current scope for this warehouse instance AdapterTransaction transaction = TransactionScope.Current[instanceId]; //Transaction not enlisted, create one if (transaction == null) { transaction = CreateTransaction(instanceId); } return(transaction); }
/// <summary> /// Transmits a message as part of a transaction /// </summary> /// <param name="msg">The message to transmit</param> /// <param name="transaction">The transaction in which the message is enlisted</param> /// <exception cref="WarehouseAdapterException"> /// </exception> public void TransmitMessage(MultiPartMessage msg, AdapterTransaction transaction) { bool autoTransaction = false; try { //Auto create transaction if not defined if (transaction == null) { autoTransaction = true; Uri sendUri = msg.Metadata.Read("SendUri") as Uri; //The warehouse instance is the host part of the uri transaction = CreateTransaction(sendUri.Host); } MultiPartMessage responseMsg = null; IDbTransaction dbTransaction = (IDbTransaction)transaction.UnderlyingTransaction; using (DbCommandWrapper command = CreateDbCommand(msg)) { command.Command.Transaction = dbTransaction; command.Command.Connection = dbTransaction.Connection; responseMsg = ExecuteCommand(command, msg.MessageType); } if (responseMsg.Properties.Contains("ALMID_O")) { if (responseMsg.Properties.Read("ALMID_O").GetType() != DBNull.Value.GetType()) { string almId = responseMsg.Properties.ReadAsString("ALMID_O"); string nLangCod = ""; if (msg.Metadata.Contains("LanguageCode")) { nLangCod = msg.Metadata.ReadAsString("LanguageCode"); } string alarmText = GetAlarmText(almId, nLangCod, dbTransaction.Connection, dbTransaction); throw new WarehouseAdapterException(almId, alarmText); } } if (autoTransaction && (transaction.State == TransactionState.Started)) { Commit(transaction); } responseMsg.Metadata.Write("CorrelationId", msg.MessageId); OnMessageReceived(responseMsg, transaction.EndPoint); } catch (Exception) { if ((transaction != null) && (autoTransaction) && (transaction.State == TransactionState.Started)) { Abort(transaction); } throw; } }
/// <summary> /// Callback method to abort a transaction that was started by this adapter. /// </summary> /// <param name="transaction">The transaction to abort.</param> public void Abort(AdapterTransaction transaction) { if (transaction == null) { throw new ArgumentNullException("transaction"); } IDbTransaction dbTransaction = transaction.UnderlyingTransaction as IDbTransaction; try { //Rollback transaction dbTransaction.Rollback(); transaction.State = TransactionState.Aborted; } catch (OracleException ex) { throw new AdapterException("The transaction could not be aborted.", ex); } catch (DbException ex) { throw new AdapterException("The transaction could not be aborted.", ex); } catch (InvalidOperationException ex) { throw new AdapterException("The transaction could not be aborted.", ex); } finally { //Close the connection try { ((WarehouseAdapterEndPoint)transaction.EndPoint).Connection.Close(); } catch (OracleException) { } catch (DbException) { } catch (InvalidOperationException) { } finally { //Dispose the connection and destroy the endpoint try { ((WarehouseAdapterEndPoint)transaction.EndPoint).Connection.Dispose(); } catch (OracleException) { } catch (DbException) { } finally { OnEndPointDestroyed(transaction.EndPoint); } } } }