Приостановка функции Azure до тех пор, пока Entity Framework не внесет изменения - PullRequest
1 голос
/ 20 сентября 2019

У меня есть функция Azure (триггер Iot-концентратора), которая:

  1. выбирает первую 1 запись, упорядоченную по времени в порядке убывания
  2. сравнивается с новой записью, которая приходит
  3. записывает приходящую запись только в том случае, если она отличается от выбранной (некоторые поля различаются)

Проблема возникает, когда записи очень быстро входят в функцию лазури - в результате я получаю дубликатыв базе данных.Я полагаю, это потому, что у SQL Server недостаточно времени для внесения изменений в базу данных к моменту поступления следующей записи и выбора функции Azure, а когда функция Azure выбирает последнюю запись, она фактически получает устаревшую.

Я использую EF Core.

1 Ответ

0 голосов
/ 20 сентября 2019

Я верю, что нет проблем с функцией, но с транзакционным характером операции, которую вы описали.Чтобы решить вашу проблему тривиально, вы можете попробовать использовать транзакцию с наивысшим уровнем изоляции:

        using (var transaction = new TransactionScope(
            TransactionScopeOption.Required,
            new TransactionOptions
            {
                // With this isolation level all data modifications are sequential
                IsolationLevel = IsolationLevel.Serializable
            }))
        {
            using (var connection = new SqlConnection("YOUR CONNECTION"))
            {
                connection.Open();

                try
                {
                    // Run raw ADO.NET command in the transaction
                    var command = connection.CreateCommand();
                    // Your reading query (just for example sake)
                    command.CommandText = "SELECT TOP 1 FROM dbo.Whatever";
                    var result = command.ExecuteScalar();

                    // Run an EF Core command in the transaction
                    var options = new DbContextOptionsBuilder<TestContext>()
                        .UseSqlServer(connection)
                        .Options;

                    using (var context = new TestContext(options))
                    {
                        context.Items.Add(result);
                        context.SaveChanges();
                    }

                    // Commit transaction if all commands succeed, transaction will auto-rollback
                    // when disposed if either commands fails
                    transaction.Complete();
                }
                catch (System.Exception)
                {
                    // TODO: Handle failure
                }
            }
        }

Вы должны настроить код под свои нужды, но у вас есть идея.

Хотя, яЯ бы предпочел полностью избежать этой проблемы и не изменять какие-либо записи, а вставлять их и выбирать последние.Транзакции сложны в применении, они могут привести к снижению производительности и возникновению взаимоблокировок в неправильном месте и неправильным образом.

...