weavejester / ragtime

Database-independent migration library
Eclipse Public License 1.0
610 stars 85 forks source link

Exception in thread "main" java.lang.Exception: Conflict! Expected .... #104

Closed 42alex closed 8 years ago

42alex commented 8 years ago

We are using ragtime 0.5.2. ragtime migrations looks like this: ... 014-mig | 2016-06-13T10:57:02.427 014-mig | 2016-06-13T10:57:02.433 014-mig | 2016-06-13T10:57:02.450 015-mig | 2016-06-13T10:57:02.499 015-mig | 2016-06-13T10:57:02.508 015-mig | 2016-06-13T10:57:02.518

When we try to apply migrations we get:

Exception in thread "main" java.lang.Exception: Conflict! Expected ragtime.repl$wrap_reporting$reify__4270@2e7da886 but ragtime.repl$wrap_reporting$reify__4270@24b2e53b was applied.         at ragtime.strategy$raise_error.invokeStatic(strategy.clj:39)         at ragtime.strategy$raise_error.invoke(strategy.clj:31)         at ragtime.core$migrate_all.invokeStatic(core.clj:43)         at ragtime.core$migrate_all.invoke(core.clj:32)         at ragtime.repl$migrate.invokeStatic(repl.clj:49)         at ragtime.repl$migrate.invoke(repl.clj:34)

Whats the problem?

42alex commented 8 years ago

We were able to resolve this issue by removing the duplicate entries from ragtime_migrations. The duplicate entries occur when several instances of the migration are executed in parallel.

danielcompton commented 8 years ago

You probably shouldn't be running database migrations in parallel against the same database? That seems like asking for trouble.

weavejester commented 8 years ago

The wrap-reporting middleware should do a better job at exposing the underlying record. Then you could see the IDs and SQL of the conflicting records.

@danielcompton is right about the underlying cause. Migrations are not made to be executed in parallel. Migrations are designed to be applied serially in a set order, so there's no benefit to running them concurrently, and many databases have locks around table creation anyway.

42alex commented 8 years ago

We expected, that the migrations (the steps) are thread safe. Obviously they are not.

weavejester commented 8 years ago

In order for the migrations to be safe to be executed concurrently, they'd need to be encased in a transaction. However, not all SQL databases support transactional DDL, and Ragtime has to cater for the lowest common denominator by default. You can, however, open up a database transaction manually, and run your migrations through that.

42alex commented 8 years ago

Is this mentioned anywhere in the docs?

weavejester commented 8 years ago

No, it hadn't occurred to me to mention it, but it's probably a good idea to point out that migrations are not implicitly wrapped in a database transaction.