go-clean-arch icon indicating copy to clipboard operation
go-clean-arch copied to clipboard

[feature]:implement transaction

Open philchia opened this issue 5 years ago • 9 comments

philchia avatar Jan 14 '20 09:01 philchia

@bxcodec I love Golang and your project. Is there any news on this? No pressure. 😄

frederikhors avatar Nov 15 '20 14:11 frederikhors

Hi @frederikhors ,

So yeah, I keep this PR open, so everyone can see all the opinions by the other.

I want to make this PR just like a reference and any new golang engineer can choose which evil side they prefer. Every opinion is valid from anyone's perspective. So since this a public PR, I don't wanna choose one and merge it, unless if it's for my private project I'll choose one and convince my team about it.

bxcodec avatar Nov 15 '20 15:11 bxcodec

@bxcodec thanks for your answer.

Since I don't know how to decide (because I'm newbie and because they all seem not 100% correct to me) I can ask you which method do you prefer?

I need to use a transaction:

  1. in a one usecase method that uses multiple repositories methods
  2. in a single method of a single repository (but here I can also do it manually)

frederikhors avatar Nov 15 '20 15:11 frederikhors

@bxcodec what do you think about this?

https://github.com/frederikhors/go-clean-arch/commit/2ec0f2d7d8d4a5f5ed076e4a1ce59eb862333ca7

I don't know how to do this:

//I can also create an helper like this:
//dbConn := db.GetTxFromCtxOrUseDBConn(ctx, m.Conn)
//instead of the below:
var dbConn interface{} // I think I need an interface for *sql.DB & *sql.Tx here
tx, ok := repository.GetTransactionFromCtx(ctx)
if ok {
    dbConn = tx
} else {
    dbConn, _ = m.Conn.BeginTx(ctx, nil)
}

Is that what you thought? To use context like this to handle transactions?

frederikhors avatar Nov 16 '20 00:11 frederikhors

If you have to use transactions across multiple repositories, it doesn't make sense to put it behind an interface anyway. Unless you'll only be dealing with different flavours of SQL databases.

nii236 avatar Nov 23 '20 04:11 nii236

@nii236 I don't understand. Can you please explain it better? Thanks.

frederikhors avatar Nov 23 '20 10:11 frederikhors

@nii236 I don't understand. Can you please explain it better? Thanks.

I would try to explain what is meant by @nii236 , the idea of defining a repository as an interface is because we're trying to make it pluggable/changeable by following the principle of Dependency Inversion, but if we use a transaction moreover if it's across multiple repositories, it would be impossible for our system to change our dependency from a SQL database into another kind of repository (NoSQL, Rest API, GRPC, or any other kind) because the concept of atomic transaction is only exist on SQL Database, then if we define those repository as an interface it would be useless because we're preparing for something that would never happen

masajip avatar Jan 26 '23 09:01 masajip

This blog post explains my thinking: https://threedots.tech/post/common-anti-patterns-in-go-web-applications/

Scroll down to "Starting with the database schema".

nii236 avatar Jan 30 '23 04:01 nii236