Почему activerecord оптимистическая блокировка работает только однажды на строку?

Вам не нужен специальный экстрактор, чтобы сделать это.

Лучшее решение - добавить один json за строкой. Затем вы можете использовать экстрактор текста и извлекать построчно. Вы также можете выбрать свой собственный разделитель.

REFERENCE ASSEMBLY [Newtonsoft.Json];
REFERENCE ASSEMBLY [Microsoft.Analytics.Samples.Formats];

    @JsonLines= 
        EXTRACT 
            [JsonLine] string
        FROM
            @Full_Path
        USING 
            Extractors.Text(delimiter:'\b', quoting : false);


@ParsedJSONLines = 
    SELECT 
        Microsoft.Analytics.Samples.Formats.Json.JsonFunctions.JsonTuple([JsonLine]) AS JSONLine
    FROM 
        @JsonLines

@AccessToProperties=
    SELECT 
        JSONLine["Property"] AS Property
    FROM 
        @ParsedJSONLines;
5
задан Sniggerfardimungus 1 May 2009 в 22:19
поделиться

3 ответа

при вызове first.save во второй раз значение some_attribute_field уже равно «first», activerecord знает об этом, поэтому он не обновляется в БД до lock_version и не увеличивается , Второе сохранение работает, так как база данных никогда не изменялась с помощью «first».

Попробуйте изменить значение во втором тесте на нечто иное, чем «first», чтобы оно отличалось от того, что находится в базе данных.

6
ответ дан 14 December 2019 в 01:16
поделиться

Как сказал Владимир, ваш тестовый / примерный код немного ошибочен. Первый не сохраняется в базе данных во время второго save! (), Потому что атрибуты не изменились. См. Следующий пример:

foo = Account.create!

first = Account.find(foo.id)
first.cash = 100
first.save!


first = Account.find(foo.id)
first.cash = 100

puts "First lock before " + first.lock_version.to_s
first.save!
puts "First lock after " + first.lock_version.to_s

это дает:

% script/runner another_tester.rb                               
First lock before 1
First lock after 1

Использование вашего примера в версии 2.3.2 rails работает так, как должно, с исключением объекта Stale при сохранении секунды (оба раза!)

1
ответ дан 14 December 2019 в 01:16
поделиться

Я не любитель Ruby, но оптимистическая блокировка мне знакома, поэтому я постараюсь помочь вам отладить ее.

Я полагаю, что второе сохранение действительно обновляет базу данных. Если оба объекта имеют разные lock_version И lock_version используется в UPDATE, это просто невозможно (UPDATE обновит нулевые строки). Итак, у нас есть только две альтернативы:

  • lock_version не используется в операторе UPDATE или используется неправильно
  • оба объекта каким-то образом получили одинаковую lock_version

( на самом деле существует третья альтернатива: оба save () находятся в их собственной транзакции, но я чувствую, что у вас AUTOCOMMIT = true )

Можете ли вы сделать видимыми фактические операторы SQL? Оператор обновления должен выглядеть примерно так:

... WHERE JOB_ID=123 AND LOCK_VERSION=8

When you ' Если у вас под рукой будут актуальные запросы, будет намного легче понять, что происходит.

PS и еще одно: в вашем примере в другой теме у вас есть этот объект:

#<Job id: 323, lock: 8, worker_host: "second">

Вызов save () может быть игнорируется контейнером, если свойства не меняются по сравнению со временем загрузки. Я не знаю, есть ли в ActiveRecord такая оптимизация или нет. Но если это так, то второй save () игнорируется, и оптимистическая блокировка не имеет шансов сработать.

2
ответ дан 14 December 2019 в 01:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: