Liquibase совершает ревизию частично - PullRequest
5 голосов
/ 31 мая 2019

Использование liquibase v3.6.3 на MySQL.Если я правильно понял, каждый CHANGESET по умолчанию запускается в транзакцию SQL.Тем не менее, мне кажется, что транзакции совершаются на основе ИЗМЕНЕНИЯ.При запуске этого сценария

databaseChangeLog:
  - changeSet:
      id: changeset-
      changes:        
         - renameTable:
            oldTableName: old_table
            newTableName: new_table
        - addColumn:
            columns:
              - column:
                  name: test_column_name
                  type: varchar(255)
                  tableName: other_table

Если тег addColumn завершается ошибкой из-за какого-то исключения SQL (например, проверки ограничений или других), таблица базы данных exchangechange не будет обновлена, чего я не ожидаю, так какне удалось изменитьТем не менее, первый оператор DID прошел, и моя таблица теперь называется new_table .

Конечно, если я исправлю проблему, вызвавшую сбой второго, и повторите попытку обновления, произойдет сбой, потому чтоold_table больше не существует.

Мне известен этот параграф в документации по liquibase

Liquibase пытается выполнить каждый changeSet в транзакции, которая фиксируется в конце, илиоткатился, если есть ошибка.Некоторые базы данных будут автоматически фиксировать операторы, которые вмешиваются в эту настройку транзакции и могут привести к неожиданному состоянию базы данных.Поэтому, как правило, лучше иметь только одно изменение на набор изменений, если только не существует группы изменений без автоматической фиксации, которые вы хотите применить в качестве транзакции, такой как вставка данных.

https://www.liquibase.org/documentation/changeset.html

но я не очень понимаю это.Автоматическая фиксация означает автоматическую фиксацию транзакции.Если все изменения включены в транзакцию, почему проходят только некоторые изменения?Должен ли liquibase откатить всю транзакцию?

Есть ли лучшие практики для этого?Разве мы не можем вручную устанавливать транзакции в жидкости?

Ответы [ 2 ]

1 голос
/ 21 июня 2019

Это не Liquibase, который совершает набор изменений частично. Я работал со многими базами данных, и основная концепция для всех баз данных, которые я использовал, заключается в том, что транзакция объединяет только модификации данных (DML).

DDL никогда не является частью транзакции. Он всегда выполняется немедленно, и открытая транзакция автоматически фиксируется перед выполнением. Причина этого заключается в том, что команда отката базы данных может обрабатывать только изменения данных. Он не может справиться с DDL. И если откат больше невозможен, то сохранение транзакции открытой становится бесполезным.

Итак, Liquibase создает транзакцию и в конце фиксирует все изменения в соответствии с состоянием дукментации. Но это работает, только если набор изменений содержит только DML, без DDL.

И поэтому DDL и DML никогда не должны смешиваться в одном наборе изменений, и каждый оператор DDL должен находиться в отдельном наборе изменений. В противном случае Liquibase не сможет предотвратить частичный успех изменений и вызвать проблемы при попытке отката.

1 голос
/ 09 июня 2019

Mysql (и многие другие реляционные базы данных) имеют концепцию неявного принятия .Большинство баз данных неявно вызывают коммит (точно так же, как вы сами вызываете COMMIT), чтобы завершить текущую активную транзакцию до (или после) выполнения операторов DDL.

Liquibase пытается применить указанные изменения одного набора изменений в рамках одной транзакции.В вашем случае есть два изменения, и оба являются операторами DDL (RENAME TABLE и ALTER TABLE), под одним набором изменений.Оба оператора вызовут неявную фиксацию, которая оставит несогласованное состояние базы данных в случае сбоя более позднего оператора.

Дополнительная информация о mysql неявном коммите на их веб-сайте, включая исчерпывающий список операторов SQL, запускающих неявные коммиты.

Надеюсь, это поможет.

...