This doesn't really solve the original problem. The reason we would put the transaction in the context is to be able to use any number of repository functions in conjuction, and have them be part of the transaction automatically, and this should all be orchestrated OUTSIDE of the db-layer. Not inside. You would typically have a service layer that calls one or more functions from the repository layer, and they would all share the transcation implicitly via the context. That's the problem with transactions in general when building a typical layered app. They are a DB-layer concern but you want to orchestrate it from the service layer so your DB-layer can be composable.
I disagree with you, txn orchestration shouldn't be part of the service layer because: * It leaks db-details into that layer, and * Makes "service" harder to test because now we have to mock a db and deal with the happy/error paths, which is outside of the goal of this layer. The goal of this video, and really the blog, is to implement repositories in such a way that could be composable (that's why the use "DBTX"). If you prefer orchestrating db-calls using the service layer, then go for it.
@@MarioCarrion Well if we ignore testing and leaking db details, because that's a separate discussion, how do you create a good composable repository layer if the service layer is not responsible for orchestrating? Let's say I have simple CRUD methods on the repo, but in the service layer, I have some specific business logi that requires me to fetch, create, delete, fetch again, and then update, all in one transaction, how do you handle that? This is a real world example from my job.
Because this is getting interesting, I created a discussion on Github, it's easier to discuss over there instead of using the youtube comments: github.com/MarioCarrion/videos/discussions/15
But what about database abstraction? What if you want to change your database to another, for example MongoDB - everithing will broken. And also, why you put transactions at the persistance layer, IMHO it wouldn't work for long buissines transactions, and transactions without details of implementation should be yoused in domain layer.
Repositories are a layer to separate datastore interactions and domain logic; database abstraction is done by defining the API your services/use cases use when interacting with repositories (in this case, the domain types and the methods/arguments the concrete repositories use). What you're saying is correct. If the database technology changes, you need to write a new implementation of those repositories. However, your services/use cases should stay the same, and that's why the transactions are defined at the persistence layer; the domain shouldn't care about the implementation details of how data is stored. Now, about the long transactions, do you have an example? Because this should work no matter what, assuming we are talking about a context that does not explicitly time out after a certain amount of time.
nice. thank You
💙
thanks!
Hi sir ,can you do a full video on go kratos framework??
This doesn't really solve the original problem. The reason we would put the transaction in the context is to be able to use any number of repository functions in conjuction, and have them be part of the transaction automatically, and this should all be orchestrated OUTSIDE of the db-layer. Not inside. You would typically have a service layer that calls one or more functions from the repository layer, and they would all share the transcation implicitly via the context.
That's the problem with transactions in general when building a typical layered app. They are a DB-layer concern but you want to orchestrate it from the service layer so your DB-layer can be composable.
I disagree with you, txn orchestration shouldn't be part of the service layer because:
* It leaks db-details into that layer, and
* Makes "service" harder to test because now we have to mock a db and deal with the happy/error paths, which is outside of the goal of this layer.
The goal of this video, and really the blog, is to implement repositories in such a way that could be composable (that's why the use "DBTX").
If you prefer orchestrating db-calls using the service layer, then go for it.
@@MarioCarrion Well if we ignore testing and leaking db details, because that's a separate discussion, how do you create a good composable repository layer if the service layer is not responsible for orchestrating?
Let's say I have simple CRUD methods on the repo, but in the service layer, I have some specific business logi that requires me to fetch, create, delete, fetch again, and then update, all in one transaction, how do you handle that? This is a real world example from my job.
Because this is getting interesting, I created a discussion on Github, it's easier to discuss over there instead of using the youtube comments: github.com/MarioCarrion/videos/discussions/15
But what about database abstraction? What if you want to change your database to another, for example MongoDB - everithing will broken. And also, why you put transactions at the persistance layer, IMHO it wouldn't work for long buissines transactions, and transactions without details of implementation should be yoused in domain layer.
Repositories are a layer to separate datastore interactions and domain logic; database abstraction is done by defining the API your services/use cases use when interacting with repositories (in this case, the domain types and the methods/arguments the concrete repositories use). What you're saying is correct. If the database technology changes, you need to write a new implementation of those repositories. However, your services/use cases should stay the same, and that's why the transactions are defined at the persistence layer; the domain shouldn't care about the implementation details of how data is stored.
Now, about the long transactions, do you have an example? Because this should work no matter what, assuming we are talking about a context that does not explicitly time out after a certain amount of time.