这个问题可能不仅仅针对Azure功能,但对我来说这就是场景。我有一个 azure 的函数,它正在处理来自服务总线主题订阅的消息。消息用于在 sql azure 服务器上的表中添加/更新数据。
对于数据库操作,我使用 Entity Framework 6.2
我的消息可以是 100 条,但也可能只有第一条消息是应该在数据库中插入条目的消息,接下来的几条消息是同一记录的更新。
现在,在我的 Azure 函数中,我的 host.json 如下所示。
{
"serviceBus": {
"maxConcurrentCalls": 16,
"prefetchCount": 20,
"autoRenewTimeout": "00:05:00"
}
}
这意味着它应该能够同时处理 16 条消息,它确实做到了。
但是,通过并发处理, Entity Framework 上下文不会从并行运行的事务中更新,最终我会得到 10 行,而数据库中应该只有 1 行,因为它本质上是相同的记录。
是否有 Entity Framework 特定的解决方案?
最佳答案
您想要做的是将属于同一实体的消息的处理次数限制为一次 1 条。有几种方法可以做到这一点:
要在 Entity Framework 级别解决此问题,您需要将读写操作正确包装到具有可序列化隔离级别的单个事务中。然而,这并没有多大意义:您对消息进行并行处理,但在数据库级别使用昂贵的锁来限制并行化。
使用数据库级约束,例如唯一索引,然后确保每条消息都为同一实体插入具有相同唯一键的行。尝试写入它的第二个操作将收到约束违规异常,将重试导致更新的操作。
只需将
maxConcurrentCalls
限制为1
,并且永远不要运行多个 Function 实例。这是最简单的方法,但显然它无法适应更高的负载。基于实体 key 使用服务总线 session ,即将相同实体的消息发送到同一 session 。但坏消息是:Azure Functions 不支持服务总线 session ,因此您必须退回到手动处理。
使用例如事件中心而不是服务总线订阅。按实体 ID 对事件进行分区,然后按照 In order event processing with Azure Functions 中所述配置您的函数。 .
关于c# - Entity Framework 并发和 Azure 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49002306/