gpt4 book ai didi

c# - 如何在多任务环境中防止在azure表中重复插入?

转载 作者:行者123 更新时间:2023-12-03 01:55:10 25 4
gpt4 key购买 nike

我有一个多任务应用程序,其中多个任务同时运行。每个任务都会检查 azure 表中是否已存在 recordId。如果没有,它会添加它。我的问题是,尽管我已经对 recordId 应用了检查,但仍然添加了重复的条目。

public async Task<bool> TryExecuteAsync(ServiceCommandMessage commandMessage, CancellationToken token, IProgress<string> progress)
{
token.ThrowIfCancellationRequested();
var isSuccessful = true;

return await System.Threading.Tasks.Task.Run(() =>
{
token.ThrowIfCancellationRequested();

var watch = new Stopwatch();
watch.Start();

try
{
StoreFourSqaureMetadata(id);
}

catch (Exception ex)
{
isSuccessful = false;
throw ex;
}

watch.Stop();

return isSuccessful;
}, token);
}
public static void StoreFourSqaureMetadata(string Id)
{
var noDataAvailable = "No data available".Trim();
try
{
var d = IsExist(Id); //Checking if Id already exist in Table
if (d != null) return;
//If not add to table

}
}

最佳答案

我认为解决您的问题的最佳解决方案有两个相当不言自明的部分:(1)在表中的适当列上创建唯一键; (2) 捕获插入失败后的错误。

唯一的 key 确实是重要的部分。这是确保此类事情不会发生的唯一方法,因为数据库是架构中唯一能够保证这种一致性的部分。

在这可能成为问题的地方,我使用类似这样的模式。首先,我有一组帮助我重试的辅助方法:

/// <summary>
/// Try a given async action 'n' times or until it succeeds.
/// </summary>
/// <param name="times">The number of times to retry the action</param>
/// <param name="action">The action to retry</param>
/// <param name="pauseInMilliseconds">The amount of time in milliseconds to pause between retries (defaults to 0)</param>
public async static Task<T> RetriesAsync<T>(this int times, Func<int, Task<T>> action, int pauseInMilliseconds)
{
var attempt = 0;
var result = default(T);
while (attempt < times)
{
try
{
result = await action(attempt);
break;
}
catch (Exception)
{
attempt++;
if (attempt >= times)
{
throw;
}
}
if (pauseInMilliseconds > 0)
{
await Task.Delay(pauseInMilliseconds);
}
}
return result;
}

然后我有方法检查该行是否存在;如果是,则返回;如果没有,则插入然后返回。其工作原理有点像这样:

private async Task<Customer> CreateOrGetCustomer(IEntities db, int customerId)
{
var customer = await db.Customers.FirstOrDefaultAsync(x => x.CustomerId == customerId);
if (customer == null)
{
customer = new Customer { CustomerId = customerId };
db.Customers.Add(customer);
await db.SaveChangesAsync();
}
return customer;
}

然后我通过重试调用该方法,如下所示:

var customer = await 2.RetriesAsync(async x => CreateOrGetCustomer(db, customerId));

我确信有更优雅的方法可以做到这一点,但它是有效的 - 至少,如果您在表上配置了所有适当的唯一键,它是有效的。

认为这两部分是相当不言自明的,但如果您需要更多关于它们的指导,或者它们由于某种原因不适合您,请告诉我。

关于c# - 如何在多任务环境中防止在azure表中重复插入?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24074136/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com