Выполнение нескольких операторов mysql в одной транзакции в инструменте миграции Mybatis - PullRequest
2 голосов
/ 21 марта 2011

Я использую инструмент миграции Mybatis для поддержки схемы в нашей базе данных, но у меня возникла следующая проблема.

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

Это действительно расстраивает, потому что нет способа поддерживать постоянное состояние БД, если вся миграция не является автономной.

Настройки

вот (соответствующая) настройка mybatis mygration для нашей тестовой базы данных.

## JDBC connection properties.
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/gamealert_test?allowMultiQueries=true
username=gamealert
password=********

# If set to true, each statement is isolated
# in its own transaction.  Otherwise the entire
# script is executed in one transaction.
auto_commit=false

# This controls how statements are delimited.
# By default statements are delimited by an
# end of line semicolon.  Some databases may
# (e.g. MS SQL Server) may require a full line
# delimiter such as GO.
delimiter=;
full_line_delimiter=false

# This ignores the line delimiters and
# simply sends the entire script at once.
# Use with JDBC drivers that can accept large
# blocks of delimited text at once.
send_full_script=true

Я добавил auto_commit = false, send_full_script = true и allowMultiQueries = true (для URL) в попытке сохранить всю миграцию в одной транзакции.

Есть ли какие-либо параметры mysql url, которые мне нужно использовать, чтобы разрешить это? Это вообще возможно? Похоже, так и должно быть. Может быть, нам просто нужно создать одну миграцию для каждого оператора, но это кажется чрезмерным.

Пример

Вот еще один пример для уточнения

Пример миграции 20110318154857_fix_daily_sales:

--// fix daily_sales naming
-- Migration SQL that makes the change goes here.

ALTER TABLE `daily_sales` CHANGE COLUMN `storeId` `store_id` INT(10) UNSIGNED NOT NULL;

b0rked;

--//@UNDO
-- SQL to undo the change goes here.
... undo sql here ....

Если я запустил миграцию, произойдет сбой из-за строки b0rked;, как и ожидалось. Статус миграции показывает, что миграция ожидает выполнения, как и ожидалось.

20110318130407 2011-03-18 17:06:24 create changelog
20110318144341 2011-03-18 17:06:30 fix schedule naming
20110318154857    ...pending...    fix daily sales naming

однако в мою базу данных внесены изменения! не хорошо!

describe daily_sales;
+-----------+------------------+------+-----+---------+-------+
| Field     | Type             | Null | Key | Default | Extra |
+-----------+------------------+------+-----+---------+-------+
| store_id  | int(10) unsigned | NO   | PRI | NULL    |       |
| sale_date | date             | NO   | PRI | NULL    |       |
| type_id   | int(10) unsigned | NO   | PRI | NULL    |       |
| tokens    | int(10) unsigned | NO   |     | 0       |       |
| dollars   | double           | NO   |     | 0       |       |
+-----------+------------------+------+-----+---------+-------+
5 rows in set (0.00 sec)

Есть ли способ предотвратить это? Должен ли я просто поместить каждое утверждение в миграцию и продолжить? вот где я сейчас.

Заранее спасибо.

1 Ответ

2 голосов
/ 25 марта 2011

DML никогда не является транзакционным - применяется немедленно.Нет возможности откатить его обратно

...