Here is my code
using (var context = DbContextCreator.Create())
{
var transactionOptions = new TransactionOptions { Timeout = TransactionManager.DefaultTimeout }; // 60 seconds.
using (var dbContextTransaction = new TransactionScope(TransactionScopeOption.Required, transactionOptions))
{
try
{
context.Database.ExecuteSqlCommand("SELECT TOP 1 Id FROM SRE.ActionHistory WITH (TABLOCKX, HOLDLOCK)");
bool isDuplicated = context.ActionHistory
.Any(x => x.StatusId == (int)eActionHistoryStatus.Pending &&
x.ActionId == (int)Action &&
x.DateTime >= timeToCheck &&
x.CustomerId == Customer.Id);
if (!isDuplicated)
{
context.ActionHistory.Add(actionHistory);
context.SaveChanges();
dbContextTransaction.Complete();
return actionHistory;
}
throw new BizException(BizErrorCodes.NotAllowedToDoAction);
}
catch (Exception ex)
{
// It will roll back automatically if the Complete() method isn't invoked or the timeout takes longer than the specified timeout.
throw;
}
}
}
}
I have two servers one for .NET code and the other for the database.
The server that I expect to failover is the server that holds the .NET code.
Actually, I need to release the lock even if the server fails.
To make my code clean, which one I should use Transaction Scope or BeginTransaction?
SQL Server will rollback the transaction when the SQL client connection is terminated due to the failover.