Can trManager manage a transaction if queries to the database are launched in parallel in different goroutines?
Closed this issue · 3 comments
MaxBoych commented
For example:
trManager.Do {
g := errGroup{}
g.Go func1{ updateDB() }
g.Go func2{ updateDB() }
g.Go func3{
updateDB()
time.Sleep(5 seconds)
return err // will the transaction work correctly?
}
return g.Wait()
}
maranqz commented
Hello,
Fast answer is yes but there is some restrictions.
- Creating nested transaction / savepoints could create problems.
- If a database driver, not to be confused with the driver in the trm library, supports concurrency processing.
Also, you can use -race
option to check race condition problems.
Could you share more about your use case or more details code?
MaxBoych commented
Thanks for the quick reply!
Sure, here are some details. I connect to different tables in the same database:
import (
trmsqlx "github.com/avito-tech/go-transaction-manager/sqlx"
"github.com/jmoiron/sqlx"
)
type FirstRepository struct {
db *sqlx.DB
txGetter *trmsqlx.CtxGetter
}
type SecondRepository struct {
db *sqlx.DB
txGetter *trmsqlx.CtxGetter
}
type ThirdRepository struct {
db *sqlx.DB
txGetter *trmsqlx.CtxGetter
}
//...
trManager := manager.Must(trmsqlx.NewDefaultFactory(postgresDB))
firstRepo = firstRepository.NewFirstRepository(postgresDB, trmsqlx.DefaultCtxGetter)
secondRepo = secondRepository.NewSecondRepository(postgresDB, trmsqlx.DefaultCtxGetter)
thirdRepo = thirdRepository.NewThirdRepository(postgresDB, trmsqlx.DefaultCtxGetter)
job := NewJob(
trManager,
firstRepo,
secondRepo,
thirdRepo,
)
//...
type Job struct {
trManager *manager.Manager
firstRepo FirstRepo
secondRepo SecondRepo
thirdRepo ThirdRepo
}
func (j *Job) Update() {
g, ctx := errgroup.WithContext(ctx)
g.Go(func() error {
return j.firstRepo.Update()
}
g.Go(func() error {
return j.secondRepo.Update()
}
g.Go(func() error {
return j.thirdRepo.Update()
}
return g.Wait()
}
maranqz commented
I don't see problems but I cannot run and see full code.
However, you don't send ctx
in Update
and a transaction would not be sent inside repository.