gpt4 book ai didi

entity-framework - 云互斥: Cloud based concurrency involving read/write to shared data (SQL data)

转载 作者:行者123 更新时间:2023-12-02 23:21:30 25 4
gpt4 key购买 nike

背景:我们有一个 Azure .NET 应用程序,需要在其中向多个后端提供商注册单个“前端”用户。由于此注册需要更长的时间,因此我们将其卸载到辅助角色,并且有多个辅助角色。所有数据都存储在 Azure SQL 中,我们使用 Entity Framework 5.0 作为 ORM。按照我们当前的设置方式,我们从 SQL dB 中读取 => 辅助角色代码中的流程 => 写入/更新到 SQL dB 以标记完成。本质上,我需要解决传统的“多线程+共享数据写入”问题,但不是操作系统规模,而是云规模。

问题:如果第一个工作人员花费的时间超过可见性超时时间,我们就会遇到多个工作人员的竞争条件。例如,假设有两个辅助角色,我在下面标记了两者如何从 SQL 读取,认为处理仍处于挂起状态,并且两者都将继续进行。它会导致最后写入者获胜的竞争条件,并在外部服务提供商上创建孤立帐户和额外帐户。

问题:我该如何修改它以优雅地处理这种情况?我可以更改数据流或对互斥体使用每用户“云”锁。在不试图限制任何人的想法的情况下,过去我推测有一个SQL based cloud lock ,但无法真正让它在 EF5.0 中工作。在这里我试图探索任何答案,无论是否基于 SQL 的锁。

// Read message off Service Bus Queue
// message invisible for 1 min now, worker must finish in 1 min
BrokeredMessage qMsg = queueClient.Receive();

// Extract UserID Guid from message
Guid userProfileId = DeserializeUserIdFromQMsg(qMsg);

// READ PROFILE FROM SQL
UserProfile up = (from x in myAppDbContext.UserProfiles select x).SingleOrDefault(p => p.UserProfileId == userProfileId);

if (up != null)
{
List<Task> allUserRegTasks = new List<Task>();

string firstName = up.FirstName; // <== WORKER ROLE #2 HERE
string lastName = up.LastName;
string emailAddress = up.Email;

// Step 1: Async register User with provider #1, update db
if (String.IsNullOrEmpty(up.Svc1CustId))
{
// <== WORKER ROLE #1 HERE
Svc1RegHelper svc1RegHelper = new Svc1RegHelper();
Task svc1UserRegTask = svc1RegHelper.GetRegisterTask(userProfileId, firstName, lastName, emailAddress);
svc1UserRegTask.Start(); // <== SQL WRITE INSIDE THIS (marks "up.Svc1CustId")
allUserRegTasks.Add(svc1UserRegTask);
}

// Step 2: Async register User with provider #2, update db
if (String.IsNullOrEmpty(up.Svc2CustId))
{
Svc2RegHelper svc2RegHelper = new Svc2RegHelper();
Task svc2UserRegTask = svc2RegHelper.GetRegisterTask(userProfileId, firstName, lastName, emailAddress);
svc2UserRegTask.Start(); // <== SQL WRITE INSIDE THIS (marks "up.Svc2CustId")
allUserRegTasks.Add(svc2UserRegTask);
}

Task.WaitAll(allUserRegTasks.ToArray());

// Step 3: Send confirmation email to user we're ready for them!
// ...

}

最佳答案

您可以通过 blob 租约将互斥锁放入 blob 存储中。在整个事情上放置一个 try/catch,因为如果其他人使用互斥体,AcquireLease() 将失败

                var lockBlobContainer = cloudClient.GetContainerReference("mutex-container");
var lockBlob = lockBlobContainer.GetBlobReference("SOME_KNOWN_KEY.lck");
lockBlob.UploadText(DateTime.UtcNow.ToString(CultureInfo.InvariantCulture)); //creates the mutex file
var leaseId = lockBlob.AcquireLease();

try
{
// Do stuff
}
finally
{
lockBlob.ReleaseLease(leaseId);
}

关于entity-framework - 云互斥: Cloud based concurrency involving read/write to shared data (SQL data),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14223292/

25 4 0