func (tx *Transactable) Update(ub squirrel.UpdateBuilder) error {
	ub = ub.Set("updated_at", time.Now())
	return tx.Exec(ub)
}
Update executes a SQL UPDATE query, and sets the updated_at column to the server time
package database
import (
	"context"
	"database/sql"
	"fmt"
	"time"
	"github.com/Masterminds/squirrel"
	"github.com/jmoiron/sqlx"
)
type Transactable struct {
	tx               *sqlx.Tx
	transactionError error
}
var errorNilTransaction = fmt.Errorf("transaction is nil")
func (c *Connection) NewTransaction(ctx context.Context) (*Transactable, error) {
	tx, err := c.Sqlx.BeginTxx(ctx, nil)
	rtn := Transactable{tx: tx, transactionError: err}
	return &rtn, err
}
func (c *Connection) WithTx(ctx context.Context, fn func(tx *Transactable)) error {
	tx, _ := c.NewTransaction(ctx)
	if tx.Error() == nil {
		fn(tx)
	}
	err := tx.Commit()
	if err != nil {
		return err
	}
	return tx.Error()
}
func (tx *Transactable) commit() error {
	if tx.tx == nil {
		return errorNilTransaction
	}
	return tx.tx.Commit()
}
func (tx *Transactable) Rollback() error {
	if tx.tx == nil {
		return errorNilTransaction
	}
	return tx.tx.Rollback()
}
func (tx *Transactable) Commit() error {
	defer tx.Rollback()  
	if tx.Error() != nil {
		return tx.Error()
	}
	tx.transactionError = tx.commit()
	return tx.Error()
}
func (tx *Transactable) Error() error {
	return tx.transactionError
}
func (tx *Transactable) Select(modelSlice interface{}, sb squirrel.SelectBuilder) error {
	return tx.sel(tx.tx.Select, modelSlice, sb)
}
func (tx *Transactable) Get(model interface{}, sb squirrel.SelectBuilder) error {
	return tx.sel(tx.tx.Get, model, sb)
}
func (tx *Transactable) Insert(tableName string, valueMap map[string]interface{}) (int64, error) {
	if tx.Error() != nil {
		return -1, tx.Error()
	}
	ins := prepInsert(tableName, valueMap)
	res, err := tx.exec(ins)
	if err != nil {
		tx.transactionError = err
		return -1, err
	}
	id, err := res.LastInsertId()
	tx.transactionError = err
	return id, err
}
func (tx *Transactable) BatchInsert(tableName string, count int, mapFn func(int) map[string]interface{}) error {
	if tx.Error() != nil {
		return tx.Error()
	}
	if count == 0 {
		return nil
	}
	columns := []string{}
	query := squirrel.Insert(tableName)
	for idx := 0; idx < count; idx++ {
		valueMap := mapFn(idx)
		if len(valueMap) == 0 {
			continue
		}
		if len(columns) == 0 {
			for columnName := range valueMap {
				columns = append(columns, columnName)
			}
			query = query.Columns(columns...)
		}
		values := []interface{}{}
		for _, columnName := range columns {
			values = append(values, valueMap[columnName])
		}
		query = query.Values(values...)
	}
	_, err := tx.exec(query)
	tx.transactionError = err
	return err
}