Model objects can also be created through the TX transaction interface. The functionality of a Model object created through a transaction object is the same as that of one created through a DB database object, except that the former’s operations are based on transactions. Once the transaction is committed or rolled back, the corresponding Model object cannot be used further; otherwise, an error will be returned. Because the TX interface cannot be reused, a transaction object corresponds to a single transaction process and ends after Commit/Rollback.

This chapter provides a simple introduction to transaction handling methods involved in chaining operations. For more detailed information, please refer to the ORM - Transaction chapter.

Example 1: Using Transaction

To facilitate transaction operations, gdb provides a closure operation for transactions, implemented through the Transaction method, which is defined as follows:

  1. func (db DB) Transaction(ctx context.Context, f func(ctx context.Context, tx TX) error) (err error)

If the error returned by the given closure method is nil, the Commit operation is automatically executed after the closure finishes execution; otherwise, it automatically performs a Rollback.

ORM Model - Transaction - 图1tip

If a panic occurs within the closure operation, the transaction will also be rolled back.

  1. func Register() error {
  2. return g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
  3. var (
  4. result sql.Result
  5. err error
  6. )
  7. // Insert basic user data
  8. result, err = tx.Table("user").Insert(g.Map{
  9. "name": "john",
  10. "score": 100,
  11. //...
  12. })
  13. if err != nil {
  14. return err
  15. }
  16. // Insert user detail data, utilizing the user uid from the previous insertion
  17. result, err = tx.Table("user_detail").Insert(g.Map{
  18. "uid": result.LastInsertId(),
  19. "phone": "18010576258",
  20. //...
  21. })
  22. return err
  23. })
  24. }

Example 2: Using TX Chaining Operations

We can also switch the bound transaction object within chaining operations using the TX method. Multiple chaining operations can bind to the same transaction object, executing the corresponding chaining operations within that transaction object.

  1. func Register() error {
  2. var (
  3. uid int64
  4. err error
  5. )
  6. tx, err := g.DB().Begin()
  7. if err != nil {
  8. return err
  9. }
  10. // Validate the return value upon method exit,
  11. // If successful, execute tx.Commit() to commit,
  12. // Otherwise, execute tx.Rollback() to roll back.
  13. defer func() {
  14. if err != nil {
  15. tx.Rollback()
  16. } else {
  17. tx.Commit()
  18. }
  19. }()
  20. // Insert basic user data
  21. uid, err = AddUserInfo(tx, g.Map{
  22. "name": "john",
  23. "score": 100,
  24. //...
  25. })
  26. if err != nil {
  27. return err
  28. }
  29. // Insert user detail data, using the user uid from the previous insertion
  30. err = AddUserDetail(tx, g.Map{
  31. "uid": uid,
  32. "phone": "18010576259",
  33. //...
  34. })
  35. return err
  36. }
  37. func AddUserInfo(tx gdb.TX, data g.Map) (int64, error) {
  38. result, err := g.Model("user").TX(tx).Data(data).Insert()
  39. if err != nil {
  40. return 0, err
  41. }
  42. uid, err := result.LastInsertId()
  43. if err != nil {
  44. return 0, err
  45. }
  46. return uid, nil
  47. }
  48. func AddUserDetail(tx gdb.TX, data g.Map) error {
  49. _, err := g.Model("user_detail").TX(tx).Data(data).Insert()
  50. return err
  51. }