Azure QueueTrigger 函数中的问题 Insert/Update EF Core DbContext(多线程)

Issue Insert/Update EF Core DbContext in Azure QueueTrigger Function (Multi-threading)

Azure QueueTrigger 函数中使用 EF Core 2.1DbContext 时出现 PK 违规异常。猜测是由于 DbContext 的性质不是 线程安全的 ,并且 Azure 函数 运行 并行连接不同的实例。我已经阅读了很多,但我找不到解决这个问题的好方法。

这是我的场景(生产者-消费者模式):

我有一个 Scheduled Azure Function 正在调用 API 从不同的外部系统获取项目。为了获得项目所需的所有信息,我需要 运行 对其他外部服务的不同查询,因此我将其与另一个 Azure 函数分离,因此计划函数只是为每个项目排队一条消息,如“同步项目 ID 101”。

另一个 QueueTrigger 函数 每次消息排队时都会触发,因此,这意味着 不同的实例 运行 并行 .此函数必须收集特定 Project 的所有数据,这意味着对其他外部服务/API 的更多调用,以(某种)聚合有关的所有信息一个项目。恕我直言,这样做很好,因为我可以并行处理多个项目,并且可以根据需要扩展功能。

一旦我获得了所有这些 Project 信息,我想使用 EF Core 将其保存在 SQL 数据库中(问题来了)

项目数据包括项目中的用户,每个用户都有特定的GUID作为PK(来自外部系统)。这意味着我可以在不同的函数实例中重复用户 ID,这就是问题所在,因为当我尝试将用户信息保存在 SQL Table 中时,我可以得到 PK 重复异常,因为多个函数实例可以同时尝试插入相同的用户(当实例 A 检查用户是否存在时,它得到 False,但另一个实例 B 实际上正在添加此用户,因此当实例 A 尝试插入时,它失败)。

我想我可以以某种方式锁定 DbContext,但不确定是否好,因为我还有一个网站对 SQL 数据库进行查询(目前是只读查询,但将来也可能会更新).

另一个想法可能是将整个项目信息发送到另一个队列/Blob 文件,并在 Singleton 模式下使用另一个函数将数据插入 SQL。

我创建了这个项目来简化我的场景,但足以重现问题并理解问题。 https://github.com/luismanez/queuetrigger-efcore-multithreading

还有其他想法或推荐方法吗? (如果发现更好的东西,可以改变架构)

非常感谢!

一种 "more easy" 方法可能是在数据库中进行某种更新插入。有一个如何使用 EF Core 执行此操作的示例:https://www.flexlabs.org/2018/02/adding-upsert-support-for-entity-framework-core