internal static OletxTransaction GetOletxTransactionFromTransmitterPropagationToken(byte[] propagationToken)
{
ArgumentNullException.ThrowIfNull(propagationToken);
if (propagationToken.Length < 24)
{
throw new ArgumentException(SR.InvalidArgument, nameof(propagationToken));
}
Guid identifier;
OletxTransactionIsolationLevel oletxIsoLevel;
OutcomeEnlistment outcomeEnlistment;
TransactionShim? transactionShim = null;
byte[] propagationTokenCopy = new byte[propagationToken.Length];
Array.Copy(propagationToken, propagationTokenCopy, propagationToken.Length);
propagationToken = propagationTokenCopy;
// First we need to create an OletxTransactionManager from Config.
OletxTransactionManager oletxTm = TransactionManager.DistributedTransactionManager;
oletxTm.DtcTransactionManagerLock.AcquireReaderLock(-1);
try
{
outcomeEnlistment = new OutcomeEnlistment();
oletxTm.DtcTransactionManager.ProxyShimFactory.ReceiveTransaction(
propagationToken,
outcomeEnlistment,
out identifier,
out oletxIsoLevel,
out transactionShim);
}
catch (COMException comException)
{
OletxTransactionManager.ProxyException(comException);
// We are unsure of what the exception may mean. It is possible that
// we could get E_FAIL when trying to contact a transaction manager that is
// being blocked by a fire wall. On the other hand we may get a COMException
// based on bad data. The more common situation is that the data is fine
// (since it is generated by Microsoft code) and the problem is with
// communication. So in this case we default for unknown exceptions to
// assume that the problem is with communication.
throw TransactionManagerCommunicationException.Create(SR.TraceSourceOletx, comException);
}
finally
{
oletxTm.DtcTransactionManagerLock.ReleaseReaderLock();
}
var realTx = new RealOletxTransaction(
oletxTm,
transactionShim,
outcomeEnlistment,
identifier,
oletxIsoLevel,
false);
return(new OletxTransaction(realTx));
}