Hello Everyone here, I am working with Golang from last month. I want to know how to deal with transaction management. It is like in the MVC architecture, if Service Layer is performing two related operations in the single request and if any one of fails should rollback the whole transaction i.e. roll backing the changes by following DO Nothing OR Everything principal.
So If anybody knows how to deal like this, kindly reply. Your replies are valuable.
Yes Mr. nathankerr, you are right. GORM is supporting transaction management. In Java Spring Framework, DataSourceTransactionManager/HibernateTransactionManager, JTA, third party atomikos tools are there that deals with Transaction management alongwith AOP. But here, we need to handle tx manually. Suppose , I while dealing with 2 database operations in single request and if error occurs in 2nd one then it should rollback the whole transaction. So I’m asking is there any approach like same.
Resourcespanning transaction management is a hard problem in IT.
Consider this:
Write file to clouddrive
Write metadata about that file to database
Writing to DB fails due to network outage
You can’t rollback storage to clouddrive, because you have network outage.
Of course there are mechanisms available to postpone the transaction (or its backroll) until network is available again. But until those postponed measures have been taken, the world is in inconsistent state for other observers/instances of your server.
func CreateAnimals(db *gorm.DB) err {
tx := db.Begin()
// Note the use of tx as the database handle once you are within a transaction
if err := tx.Create(&Animal{Name: "Giraffe"}).Error; err != nil {
tx.Rollback()
return err
}
if err := tx.Create(&Animal{Name: "Lion"}).Error; err != nil {
tx.Rollback()
return err
}
tx.Commit()
return nil
}
This will either create both animals or none of them.
Also there are even resources available which you can’t roll back at all… Pushing a message to a MessageQueue for example… If it has been sent, then you can’t take it back. So if another failable step of the transaction relies on the message beeing sent, but does fail on itself, your message sent to the MQ does suggest to any receiver, that the following step is already done or happens at least very soon.
Hi Mr. Nathankerr, Thanks for sharing this example. Here, you are doing this Tx activities in DAO layer itself. But I want to do in Service Layer. Hope you understand what I am saying.
Seems to me like the biggest problem you are having is trying to bang Go into a Java shaped hole, and thats not what it’s intended for. The traditional MVC isn’t necessary if you think about how your application operates. This one in particular is already separated by client side, server side, and database access. GORM handles all database access after you have handled requests from the client on your server, so any scrubbing/data validation/etc can be handled by the server before it commits these to the database. You don’t have to inject a metric ton of boilerplate to conform to MVC as Java understands it, welcome to Go.
I’d check for errors on both tx.Rollback() and tx.Commit() myself. You don’t want to report success if the Commit() fails because the database transaction log is full.