github.com/johnnyeven/libtools@v0.0.0-20191126065708-61829c1adf46/mysql/trans/transaction.go (about)

     1  package trans
     2  
     3  import (
     4  	"fmt"
     5  	"runtime/debug"
     6  
     7  	"golib/gorm"
     8  )
     9  
    10  const (
    11  	internalErrorCode = 1
    12  	dbErrCode         = 2
    13  )
    14  
    15  type serverError struct {
    16  	Code int
    17  	Msg  string
    18  }
    19  
    20  const serverErrorFmt = "ErrorCode:[%d]; Msg:[%s]"
    21  
    22  func (this serverError) Error() string {
    23  	return fmt.Sprintf(serverErrorFmt, this.Code, this.Msg)
    24  }
    25  
    26  type Task func(db *gorm.DB) error
    27  
    28  func ErrHandler(db *gorm.DB, task Task) (err error) {
    29  	defer func() {
    30  		if e := recover(); e != nil {
    31  			msg := fmt.Sprintf("panic: %s; calltrace:%s", fmt.Sprint(e), string(debug.Stack()))
    32  			err = &serverError{internalErrorCode, msg}
    33  		}
    34  	}()
    35  	return task(db)
    36  }
    37  
    38  func ExecTransaction(m_db *gorm.DB, transction ...Task) error {
    39  	exec_db := m_db.Begin()
    40  	if exec_db.Error != nil {
    41  		return &serverError{dbErrCode, exec_db.Error.Error()}
    42  	}
    43  	for _, task := range transction {
    44  		if err := ErrHandler(exec_db, task); err != nil {
    45  			if rberr := exec_db.Rollback().Error; rberr != nil {
    46  				return &serverError{dbErrCode, rberr.Error()}
    47  			}
    48  			//return &serverError{dbErrCode, err.Error()}
    49  			return err
    50  		}
    51  	}
    52  
    53  	if err := exec_db.Commit().Error; err != nil {
    54  		exec_db.Rollback()
    55  		return &serverError{dbErrCode, err.Error()}
    56  	}
    57  	return nil
    58  }