Mybatis迁移工具在一个事务中运行多个mysql语句
我正在使用 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 和 allowedMultiQueries=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 ....
如果我运行 migrate up,它会因为 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)
有什么办法可以防止这种情况发生吗?我应该将每个语句放入迁移中然后继续吗?这就是我现在的情况。
提前致谢。
I'm using the Mybatis migration tool to maintain the schema to our database but I'm having the following problem.
Currently, if we use multiple statements in a migration they are each run in a separate transaction. So if I want to alter 2 tables (or run multiple statements) as part of a feature and one of them breaks, any that were run first have to be manually reverted. The mybatis migration however is only marked as complete in the changelog table if all statements completed successfully.
This is really frustrating because there's no way to maintain a constant db state if the entire migration isn't autonomous.
Settings
here's the (relevant) setting for mybatis mygration for our test database.
## 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
I've added auto_commit=false, send_full_script=true and allowMultiQueries=true (to url) in an attempt to keep the whole migration in one transaction.
Are there any mysql url parameters that I need to use to allow this? Is this even possible? Seems like it should be. Maybe we just need to create one migration for each statement but that seems excessive.
Example
Here's a further example for clarification
Example migration 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 ....
If I run migrate up it fails because of the b0rked;
line as expected.
migrate status shows the migration as pending as expected.
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
my database however has the changes applied! not good!
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)
Is there any way to prevent this? Should I just put each statement in a migration and move on? that's where I am right now.
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
DML 从来都不是事务性的——立即应用。没有办法回滚
DML is never transactional -- applied immediately. There is no way to roll it back