Skip to content

Instantly share code, notes, and snippets.

@valterlobo
Last active May 7, 2022 17:06
Show Gist options
  • Save valterlobo/491ebdfe4cc76a85efb14ca6b9116131 to your computer and use it in GitHub Desktop.
Save valterlobo/491ebdfe4cc76a85efb14ca6b9116131 to your computer and use it in GitHub Desktop.
Golang Transaction - Duvidas em pseudo-código
func criarDado(sql.Tx, ctx, dado Dado) (error) {
}
func criarItem(sql.Tx, ctx, item Item) (error) {
}
pedido ( dado:Dado, itens:[]Item )
func cadastrarPedido(pedido) (error) {
ctx := context.Background()
tx, err := sql.DB.BeginTx(ctx, nil)
errorDado := criarDado(tx, ctx, pedido.dado)
if errorDado != nil {
tx.Rollback()
return errorDado
}
para cada item no pedido.itens{
errorItem := criarItem ( tx, ctx, item )
if errorItem != nil{
tx.Rollback()
return errorItem
}
}
tx.Commit()
}
@renatosuero
Copy link

renatosuero commented Sep 25, 2020

func (tx *sql.Tx)criarDado(ctx, dado Dado) {

}
isso não funcionaria para ti ? update, eu adicionei como ponteiro

@valterlobo
Copy link
Author

Valeu - acho que vou fazer isto 👍

type DadoRepository struct {
DBConnection *sql.DB
Tx *sql.Tx
Ctx context.Context
}

type ItemRepository struct {
DBConnection *sql.DB
Tx *sql.Tx
Ctx context.Context
}

func (dadoRepository *DadoRepository) criarDado( dado Dado) (error) {
utilizar -> dadoRepository.Tx
utilizar -> dadoRepository.Ctx
ex: dadoRepository.Tx.PrepareContext(dadoRepository.Ctx , "INSERT ... " )

}

func (itemRepository *ItemRepository) criarItem(item Item) (error) {

 utilizar ->    itemRepository.Tx 
 utilizar   ->    itemRepository.Ctx

ex: itemRepository.Tx.PrepareContext(itemRepository.Ctx , "INSERT ... " )

}

//transaction

ctx := context.Background()
tx, err := repository.GlobalConnection.BeginTx(ctx, nil))
//set
dadoRepository.Tx = tx
dadoRepository.Ctx = ctx

itemRepository.Tx = tx
itemRepository.Ctx = ctx

@valterlobo
Copy link
Author

valterlobo commented Sep 25, 2020

func (tx *sql.Tx)criarDado(ctx, dado Dado) {

}
isso não funcionaria para ti ? update, eu adicionei como ponteiro

Sim vai funcionar . So coloquei a sql.Tx - nas struct.

@valterlobo
Copy link
Author

@valterlobo
Copy link
Author

valterlobo commented May 7, 2022

func GetDB () sql.DB

db, err := sql.Open("mysql",
"user:password@tcp(127.0.0.1:3306)/hello")
if err != nil {
log.Fatal(err)
}
return db
}

type Repository struct {
db *sql.DB
}

func NewRepository(db *sql.DB) Repository {

repo := &Repository{
	db:   db,
}
return repo

}

func (r Repository ) Save(d Data ) {

tx, err := r.db.BeginTx(ctx, nil)
if err != nil {
return fail(err)
}
// Defer a rollback in case anything fails.
defer tx.Rollback()

result, err := tx.ExecContext(ctx, "INSERT INTO XXXXXX (id, field ) VALUES (?, ?)",
data.ID, data.Field)
if err != nil {
return fail(err)
}
// Get the ID of the order item just created.
orderID, err := result.LastInsertId()
if err != nil {
return fail(err)
}

  _, err = tx.ExecContext(ctx, "UPDATE XXXXXX SET field_date =  ? WHERE id = ?",
    data.GetDate(), data.ID)

// Commit the transaction.
if err = tx.Commit(); err != nil {
    return fail(err)
}

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment