hagrere
@hagrere (hagurere)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

golangのsql-migrateでトランザクション処理がしたい

goのechoでCRUD APIを作ろうとしています。
migrationにsql-migrateを使おうとしていますがmigrate upでトランザクション処理が動いてくれなくて途中でエラーが出てもロールバックしてくれません。

dbはmysqlです

該当するソースコード


-- +migrate Up
SET AUTOCOMMIT = 0;
BEGIN;
create table users
(
    id int auto_increment primary key, 
    name varchar(255), 
    email varchar(255), 
    created_at timestamp
);

INSERT INTO users(id, name, email, created_at)
VALUES(1, "Yamada", "yamada@example.com", Now());
    
INSERT INTO users(id, name, email, created_at)
VALUES(2, "Tanaka", "tanaka@example.com", Now());
COMMIT;

-- +migrate Down
DROP TABLE IF EXISTS users;

実行例

例えばinsert文の中でわざとsyntaxエラーが出るようにします

root@7f56c19b7da6:/app# sql-migrate up
Migration failed: Error 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right synt

修正後もう一回upすると以下のようになります

root@7f56c19b7da6:/app# sql-migrate up
Migration failed: Error 1050: Table 'users' already exists handling 20220625100243-users.sql

downでusersを消したくてもdownが動いてくれません

root@7f56c19b7da6:/app# sql-migrate down
Applied 0 migrations

まぁmigrationとseedは分けろよって感じでもありますがなぜロールバックができないのか気になるのでわかる方いたら教えていただきたいです。

0

1Answer

MySQLのDDLはトランザクションに対応していません。
そのため提示の内容を実現したいのであれば

  • マイグレーションのバージョンをDDLとDMLで分ける
  • DML側のバージョンのみトランザクションをかける

とすると良いと思います。
※この場合DML側のdownでレコードを消す対処も必要です

1Like

Your answer might help someone💌