func (driver *Driver) Migrate(f file.File, pipe chan interface{}) { defer close(pipe) pipe <- f // http://go-database-sql.org/modifying.html, Working with Transactions // You should not mingle the use of transaction-related functions such as Begin() and Commit() with SQL statements such as BEGIN and COMMIT in your SQL code. tx, err := driver.db.Begin() if err != nil { pipe <- err return } if f.Direction == direction.Up { if _, err := tx.Exec("INSERT INTO "+tableName+" (version) VALUES (?)", f.Version); err != nil { pipe <- err if err := tx.Rollback(); err != nil { pipe <- err } return } } else if f.Direction == direction.Down { if _, err := tx.Exec("DELETE FROM "+tableName+" WHERE version = ?", f.Version); err != nil { pipe <- err if err := tx.Rollback(); err != nil { pipe <- err } return } } if err := f.ReadContent(); err != nil { pipe <- err return } f.Content = bytes.TrimSpace(f.Content) if driver.multiStatements && len(f.Content) > 0 { if _, err := tx.Exec(string(f.Content)); err != nil { pipe <- err if err := tx.Rollback(); err != nil { pipe <- err } return } } else { if err := driver.multiStatementsFallback(f.Content, tx); err != nil { pipe <- err if err := tx.Rollback(); err != nil { pipe <- err } return } } if err := tx.Commit(); err != nil { pipe <- err return } }