public static Enlistment Reenlist(
Guid resourceManagerIdentifier,
byte[] recoveryInformation,
IEnlistmentNotification enlistmentNotification)
{
if (resourceManagerIdentifier == Guid.Empty)
{
throw new ArgumentException(SR.BadResourceManagerId, nameof(resourceManagerIdentifier));
}
if (null == recoveryInformation)
{
throw new ArgumentNullException(nameof(recoveryInformation));
}
if (null == enlistmentNotification)
{
throw new ArgumentNullException(nameof(enlistmentNotification));
}
TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;
if (etwLog.IsEnabled())
{
etwLog.MethodEnter(TraceSourceType.TraceSourceBase, "TransactionManager.Reenlist");
etwLog.TransactionManagerReenlist(resourceManagerIdentifier);
}
// Put the recovery information into a stream.
MemoryStream stream = new MemoryStream(recoveryInformation);
int recoveryInformationVersion = 0;
string nodeName = null;
byte[] resourceManagerRecoveryInformation = null;
try
{
BinaryReader reader = new BinaryReader(stream);
recoveryInformationVersion = reader.ReadInt32();
if (recoveryInformationVersion == TransactionManager.RecoveryInformationVersion1)
{
nodeName = reader.ReadString();
resourceManagerRecoveryInformation = reader.ReadBytes(recoveryInformation.Length - checked((int)stream.Position));
}
else
{
if (etwLog.IsEnabled())
{
etwLog.TransactionExceptionTrace(TraceSourceType.TraceSourceBase, TransactionExceptionType.UnrecognizedRecoveryInformation, nameof(recoveryInformation), string.Empty);
}
throw new ArgumentException(SR.UnrecognizedRecoveryInformation, nameof(recoveryInformation));
}
}
catch (EndOfStreamException e)
{
if (etwLog.IsEnabled())
{
etwLog.TransactionExceptionTrace(TraceSourceType.TraceSourceBase, TransactionExceptionType.UnrecognizedRecoveryInformation, nameof(recoveryInformation), e.ToString());
}
throw new ArgumentException(SR.UnrecognizedRecoveryInformation, nameof(recoveryInformation), e);
}
catch (FormatException e)
{
if (etwLog.IsEnabled())
{
etwLog.TransactionExceptionTrace(TraceSourceType.TraceSourceBase, TransactionExceptionType.UnrecognizedRecoveryInformation, nameof(recoveryInformation), e.ToString());
}
throw new ArgumentException(SR.UnrecognizedRecoveryInformation, nameof(recoveryInformation), e);
}
finally
{
stream.Dispose();
}
DistributedTransactionManager transactionManager = CheckTransactionManager(nodeName);
// Now ask the Transaction Manager to reenlist.
object syncRoot = new object();
Enlistment returnValue = new Enlistment(enlistmentNotification, syncRoot);
EnlistmentState.EnlistmentStatePromoted.EnterState(returnValue.InternalEnlistment);
returnValue.InternalEnlistment.PromotedEnlistment =
transactionManager.ReenlistTransaction(
resourceManagerIdentifier,
resourceManagerRecoveryInformation,
(RecoveringInternalEnlistment)returnValue.InternalEnlistment
);
if (etwLog.IsEnabled())
{
etwLog.MethodExit(TraceSourceType.TraceSourceBase, "TransactionManager.Reenlist");
}
return returnValue;
}