kyokomi/goma

トランザクション制御

kyokomi opened this issue · 2 comments

txをdaoで持ち回す感じで、txがnillじゃなければ使うようにする感じ

type XxxxDao struct {
    // ...
    tx *sql.Tx
}

func (d *XxxxDao) SetTx(tx *sql.Tx) {
    d.tx = tx
}
if d.tx != nil {
    d.tx.Query()
} else {
    d.db.Query()
}

実装した。サンプルはこちら

goma/test/mysql/main.go

Lines 191 to 270 in 8cac5bd

func txTest(g Goma) {
id := int64(1234567890)
tx, err := g.Begin()
if err != nil {
log.Fatalln(err)
}
// string
dao := g.GomaStringTypes
dao.SetTx(tx)
e := entity.GomaStringTypesEntity{
ID: id,
TextColumns: "あいうえおかきくけこ",
TinytextColumns: "abc",
MediumtextColumns: "abcdefg",
LongtextColumns: "鉄1234567890abcdefghijkelmnopqrstuvwxyz1234567890abcdefghijkelmnopqrstuvwxyz柱",
CharColumns: "a",
VarcharColumns: "1234567890abcdefghijkelmnopqrstuvwxyz",
}
_, err = dao.Insert(e)
if err != nil {
log.Fatalln(err)
}
// Rollback(insertを無効にする)
if err := tx.Rollback(); err != nil {
log.Fatalln(err)
}
// Rollback後に使うならResetもしくは新しいtxを設定する
dao.ResetTx()
// 再度トランザクションをはる
tx, err = g.Begin()
if err != nil {
log.Fatalln(err)
}
dao.SetTx(tx)
// Rollbackでnilのはず
if e, err := dao.SelectByID(id); err != nil {
log.Fatalln(err)
} else {
fmt.Printf("Rollbackでnilのはず => %s: %+v\n", dao.TableName, e)
}
// Insertする
_, err = dao.Insert(e)
if err != nil {
log.Fatalln(err)
}
// Commit
if err := tx.Commit(); err != nil {
log.Fatalln(err)
}
// Commit後後に使うならResetもしくは新しいtxを設定する
dao.ResetTx()
// Commitしたのでnilじゃない
if e, err := dao.SelectByID(id); err != nil {
log.Fatalln(err)
} else {
fmt.Printf("Commitしたのでnilじゃない => %s: %+v\n", dao.TableName, e)
}
_, err = dao.Delete(id)
if err != nil {
log.Fatalln(err)
}
if e, err := dao.SelectByID(id); err != nil {
log.Fatalln(err)
} else {
fmt.Printf("普通にDeleteしてnilのはず => %s: %+v\n", dao.TableName, e)
}

db.Beginでtx取得して

dao.SetTx(tx)でトランザクションを設定する。以降このDaoはトランザクション制御内になる。

tx.Rollback()もしくはtx.Commit()で通常通り反映できる。

もし、RollbackやCommit後にもDaoを使いまわしたい時はdao.ResetTx()を呼び出す。