Ejecutando múltiples declaraciones MySQL en una transacción en la herramienta de migración de MyBatis

StackOverflow https://stackoverflow.com/questions/5380201

  •  28-10-2019
  •  | 
  •  

Pregunta

Estoy usando la herramienta de migración mybatis para mantener el esquema en nuestra base de datos, pero tengo el siguiente problema.

Actualmente, si usamos múltiples declaraciones en una migración, cada una se ejecuta en una transacción separada. Entonces, si quiero alterar 2 tablas (o ejecutar múltiples declaraciones) como parte de una característica y una de ellas se rompe, cualquiera que se ejecute primero debe ser revertida manualmente. Sin embargo, la migración de MyBatis solo se marca como completa en la tabla ChangeLog si todas las declaraciones se completan con éxito.

Esto es realmente frustrante porque no hay forma de mantener un estado de DB constante si toda la migración no es autónoma.

Ajustes

Aquí está la configuración (relevante) para mybatis mygration para nuestra base de datos de prueba.

## 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

He agregado auto_commit = false, send_full_script = true y teawMultiqueries = true (a URL) en un intento de mantener toda la migración en una transacción.

¿Hay algún parámetros de URL MySQL que necesito usar para permitir esto? ¿Es esto incluso posible? Parece que debería ser. Tal vez solo necesitamos crear una migración para cada declaración, pero eso parece excesivo.

Ejemplo

Aquí hay otro ejemplo de aclaración

Ejemplo de migración 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 ....

Si ejecuto la migración, falla debido a la b0rked; línea como se esperaba. El estado de migración muestra la migración tan pendiente como se esperaba.

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

Sin embargo, mi base de datos tiene los cambios aplicados! ¡no es bueno!

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)

hay alguna forma de prevenir esto? ¿Debería poner cada declaración en una migración y seguir adelante? Ahí es donde estoy ahora.

Gracias por adelantado.

¿Fue útil?

Solución

DML nunca es transaccional, se aplica de inmediato. No hay forma de retrasarlo

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top