遇到TransactionInDoubtException
时会发生部分提交吗?如果是这样,如何回滚提交/正确处理TransactionInDoubtException
var option = new TransactionOptions();
option.IsolationLevel = IsolationLevel.ReadCommitted
using (var scope = new TransactionScope(TransactionScopeOption.Required, option))
{
try
{
Context.SaveEmail(_emailInfoList);
context.SaveSyncState(syncState);
scope.Complete();
return true;
}
catch (TransactionInDoubtException ex)
{
// Looks like commit has already taken place
// How to roll back the changes ??
// sth like scope.Rollback()
}
}
答案 0 :(得分:0)
根据 MSDN :
尝试对事务执行操作时抛出此异常 这是有疑问的。当交易的状态时,交易是有疑问的 交易无法确定。具体来说,的最终结果 这项交易,无论是承诺还是中止,都是不可知的 事务。强>
尝试提交时也会抛出此异常 交易和交易变得毫无疑问。
这是一个可恢复的错误。
修改强>
恢复:
你必须抓住TransactionInDoubtException
&用适当的检查写补偿逻辑。
using (var scope = new TransactionScope(TransactionScopeOption.Required, option))
{
try
{
Context.SaveEmail(_emailInfoList);
context.SaveSyncState(syncState);
scope.Complete();
return true;
}
catch (TransactionInDoubtException ex)
{
//check whether any one record from the batch has been partially committed . If committed then no need to reprocess this batch.
// transaction scope should be disposed first .
scope.Dispose();
if (IsReprocessingNeeded(syncState))
throw;
return true;
}
}
/// <returns></returns>
private bool IsReprocessingNeeded(SyncStateDataModal syncState)
{
while (true)
{
try
{
var id = _emailInfoList[0].ID;
bool isEmailsCommitted = Context.GetJournalEmail().FirstOrDefault(a => a.ID == id) != null;
if (!isEmailsCommitted)
return true;
if (context.EmailSynch(syncState.Id) == null)
{
context.SaveSyncState(syncState);
}
return false;
}
catch (Exception ex)
{
Thread.Sleep(TimeSpan.FromMinutes(AppConfiguration.RetryConnectionIntervalInMin));
}
}
}
消息来源 What is the recovery path for TransactionInDoubtException ?