Skip to content

事务的使用

zouchangfu edited this page Jul 27, 2022 · 1 revision

gobatis支持事务的使用,可以通过调用session的的Tx方法,来实现事务。

如果Tx方法返回的是nil,则自动提交事务,如果返回的是error或者抛出异常则触发回滚

自动提交

下面例子中Tx返回nil,自动提交事务。

func TestTestTable_Insert(t *testing.T) {
  testTable := TestTable{}
  gobatis.RegisterModel(&testTable)
  
  // 注册SQL,这里的方式就是代替了XML的写法
  gobatis.RegisterSql("insert_id", "insert into test_table (id, username, password) "+
    "values (#{TestTable.id}, #{TestTable.username}, #{TestTable.password})")
  gobatis.RegisterSql("select_id", "select * from test_table where id = #{TestTable.id}")

  var resultTestTable TestTable
  db.SessionManager.NewSession().Tx(func(session *gobatis.Session) error {
    result := 0
    err := session.Insert("insert_id").Param(TestTable{Id: 41, Username: "user5", Password: "pw5"}).Result(&result)
    if err != nil {
      return err
    }
    t.Logf("result %d\n", result)
    session.Select("select_id").Param(TestTable{Id: 41}).Result(&resultTestTable)
    t.Logf("data: %v", resultTestTable)
    //commit
    return nil
  })
}

gobatis.RegisterSql是注册SQL语句的另外一种方式,这里的insert_id代表的是XML中Select标签的Id,SQL语句代表的是XML标签中的SQL语句。

image

Error回滚

下面这个例子返回的是错误,所以内部自动进行回滚。

func TestTestTable_InsertTxRollback(t *testing.T) {
  testV := TestTable{}
  gobatis.RegisterModel(&testV)
  gobatis.RegisterSql("insert_id", "insert into test_table (id, username, password) "+
    "values (#{TestTable.id}, #{TestTable.username}, #{TestTable.password})")
  gobatis.RegisterSql("select_id", "select * from test_table where id = #{TestTable.id}")
  var resultTestTable TestTable
  db.SessionManager.NewSession().Tx(func(session *gobatis.Session) error {
    result := 0
    err := session.Insert("insert_id").Param(TestTable{Id: 40, Username: "user", Password: "pw"}).Result(&result)
    if err != nil {
      return err
    }
    t.Logf("ret %d\n", result)
    session.Select("select_id").Param(TestTable{Id: 40}).Result(&resultTestTable)
    t.Logf("data: %v", resultTestTable)
    // rollback
    return errors.New("rollback! ")
  })
}

Panic回滚

这里手动提交panic,自动触发回滚事务

func Test_InsertTxPanicRollback(t *testing.T) {
  testV := TestTable{}
  gobatis.RegisterModel(&testV)
  gobatis.RegisterSql("insert_id", "insert into test_table (id, username, password) "+
    "values (#{TestTable.id}, #{TestTable.username}, #{TestTable.password})")
  gobatis.RegisterSql("select_id", "select * from test_table where id = #{TestTable.id}")
  var resultTestTable TestTable
  db.SessionManager.NewSession().Tx(func(session *gobatis.Session) error {
    result := 0
    err := session.Insert("insert_id").Param(TestTable{Id: 102, Username: "user", Password: "pw"}).Result(&result)
    if err != nil {
      return err
    }
    t.Logf("ret %d\n", result)
    session.Select("select_id").Param(TestTable{Id: 102}).Result(&resultTestTable)
    t.Logf("data: %v", resultTestTable)
    
    // rollback
    panic("rollback! ")

    return nil
  })
}

总结

Tx 开启事务执行语句

返回nil则提交,返回error回滚

抛出异常错误触发回滚