Mike
Mike

Reputation: 878

Share db connection

First of all I read this article: https://www.alexedwards.net/blog/organising-database-access

Basically almost all articles suppose to store db connection in repository struct.

But suppose there is this case: We have 2 repositories Also have some handle. In this handle we have to read some model from the first repository. Then create another model and insert in to the second repository. And we have to do in transaction.

If we store db connection in each repositories: in the first repository we begin transaction, and then we cannot use this transaction in the second repository.

I thought about these solution: 1.

func (self *handles) SomeHandle(ctx context.Context) {
   dbConnection := self.acquireConnectionFromPool();
   dbConnection.beginTransaction();
   // skip errors checking
   model := self.repositoryOne.get(dbConnection);
   // create new model
   self.repositoryTwo.save(dbConnection, newModel);
   dbConnection.commit();
}
func (self *handles) SomeHandle(ctx context.Context) {
   dbConnection := self.acquireConnectionFromPool();
   dbConnection.beginTransaction();
   ctxDb := context.WithValue(ctx, "db", dbConnection)
   // skip errors checking
   model := self.repositoryOne.get(ctxDb);
   // create new model
   self.repositoryTwo.save(ctxDb, newModel);
   dbConnection.commit();
}

Which solution is better?

Upvotes: 0

Views: 117

Answers (1)

Eduard Hasanaj
Eduard Hasanaj

Reputation: 895

sql.DB is more than a connection to your database. It abstracts away the connection handling from you by creating/pooling connections as needed. It is safe to reuse one sql.DB everywhere in your repositories. This conclusion can be draw from docs where it is stated:

SetConnMaxIdleTime sets the maximum amount of time a connection may be idle.

The above definition is enough to conclude that sql.DB is not a connection but an interface which provides generic access to the database by abstracting away driver/connection implementation.

Upvotes: 3

Related Questions