Wrap DB Transaction with Abstraction Golang
I want to show you how to write DB transaction with abstraction
in Flat Architecture on my previous article
You can read it first here Best Way To Structuring Golang Code
before continue
Okayy . . .
Now for last code I created, I’ve little modification to support abstract transaction
so for the first, we move adapter.go
to api
directory, because we need to create sub abstraction from parent interface
the code look like this
api/adapter.go
if you realize from previous code, I add 2 function CreateSomething
this function will insert data to DB, and WrapTx
this will wrap entire parent interface in function argument
this function argument will handle abstract function from SqlDB
struct in adapters
so when you call WrapTx
you can call abstract function SqlDB
inside function argument
Next I add some function in adapters/sql.go
I Create SqlDBTx
struct for handled new sub abstraction from function argument and TxConn
to handled Tx connection inside WrapTx
this is the code of WrapTx
function
As you can see, first we call sqldb.sqlConn.Begin()
as tx connection
and we apply this tx
to function TxConn
this will return interface from api/adapter.go
so we put this return to fn
which is function argument
and what should we do in here is only grab the error, so when we got errors
from this fn(q)
, this WrapTx
function will do rollback transaction
otherwise they will return Commit().Error
this will return error when you got error or nil when success
Next I was updated code hello_service.go
to call function WrapTx
from bussiness logic
So when we call WrapTx
the function will look like this
inside of function argument you can call the abstraction from current connection (DB you use)
also you can call other function not only from that function argument.
As you can see, I call failTx
function from outside function argument, so this will simulate your transaction to fail
you just need to return error when you want to rollback this transaction
it’s very simple right !
Benefit
So what is benefit for using this abstraction in Flat Architecture ?
Your code will . . .
- easy to maintain
i.e when you want to change to other DB with different transaction function
you don’t need to change the bussiness logic,
you just need to add new DB in adapters and implementWrapTx
and write the transaction code inside this function with requirement from DB it self - easy to read and simple
As you can see, you don’t need to call rollback on every statement,
just return error then they will rollback automaticly
you can check full code here https://github.com/Aris-haryanto/Best-Way-To-Structuring-Golang-Code/tree/abstract_transaction