我正在寻找一种 C# 模式来编码同步操作,包括针对特定实体写入两个不同的数据库,这样我就可以避免同一实体上同时操作的竞争条件。
例如线程 1 和线程 2 同时处理实体 X 上的操作。该操作将 X 的信息写入数据库 A(在我的例子中,更新插入到 MongoDB)和数据库 B(插入到 SqlServer)。线程 3 正在实体 Y 上处理相同的操作。所需的行为是:
- 线程 1 在处理实体 X 对 A 和 B 的写入时阻塞线程 2。
- 线程 2 等待线程 1 完成对 A 和 B 的写入,然后为实体 X 写入 A 和 B。
- 线程 3 不会被阻塞,并且在线程 1 正在处理时处理实体 Y 的 A 和 B 写入
我试图避免的行为是:
- 线程 1 向 A 写入实体 X。
- 线程 2 向 A 写入实体 X。
- 线程 2 向 B 写入实体 X。
- 线程 1 向 B 写入实体 X。
我可以在所有线程中使用互斥体,但我真的不想阻止不同实体的操作。
最佳答案
我建议使用简单的锁(如果它位于代码的一个区域),因为它将处理不同的对象(即.net对象)但具有相同的值(因为它是相同的实体)我宁愿去具有某种形式的实体代码。如果实体有某种形式的代码,我会使用它 - 例如:
但是,当然,您必须提防死锁。 String.Intern 很棘手,因为只要应用程序运行,它就会实习字符串。
lock(String.Intern(myEntity.Code))
{
SaveToDatabaseA(myEntity);
SaveToDatabaseB(myEntity);
}
但看起来您想要某种复制机制。那么我宁愿在数据库级别上进行(而不是在代码级别上)
[更新]
您用信息更新了问题,该问题正在多个服务器上完成。这个信息在这里很重要:)普通的锁不起作用。
当然,您可以尝试跨不同服务器同步锁,但这就像分布式事务一样。从理论上讲,您可以做到这一点,但大多数人只是尽可能避免它,并且他们利用解决方案的架构来简化流程。
[更新2]
您可能还会发现这很有趣:Distributed locking in .NET
:)
关于c# - 如何编写以实体 id 为条件的 C# 互斥 block ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61642256/