is it appropriate to use a Dbadapter per-request?
pdonovan-merit opened this issue · comments
We are currently modifying our codebase to instantiate a dbadapter per-request to our system, which is an HTTP web service, giving us control over the root database transaction as well as the context passed to the dbadapter and its gorm.db on instantiation. We were wondering if this is a totally inappropriate use of the adapter or there are better recommended patterns.
We have also run into some issues with transactions as a result of this usage (since the adapter does, in some cases, start a transaction with .Begin, and Gorm doesn't like creating nested transactions that way).
Basically, what we'd like to do is wrap the DbAdapter's operations with a database transaction that is created and managed as part of a service call.
Every time an Enforcer is created with the adapter, it will load all the policies from the database. So if you have too many policies, initialization of the enforcer for each request is not recommended. However, initialization of the adapter and then calling e.SetAdapter()
takes no cost other than authing connection with DB (note: if the content in DB is changed, you need to call e.LoadPolicy()
manually 😣).
Transaction is only used in UpdateFilteredPolicies()
and UpdatePolicies()
by the `gorm-adapter. You can use functions other than these two.
BTW, I find the Gorm seems to have the support for nested transactions https://gorm.io/docs/transactions.html#Nested-Transactions . Perhaps you can write the following way(NOT tested, just a proof-of-concept):
func handler(……)
{
tx = db.Begin()
// tx.Create(...) some operations
// begin nested transaction
a, _ := adapter.NewAdapterByDB(tx)
e.SetAdapter(a)
e.UpdatePolicies(....) // do some operations
a, _ = adapter.NewAdapterByDB(db)
e.SetAdapter(a)
// tx.Create(...) // the left operations
tx.Commit()
}
Hoping this will help you. @pdonovan-merit
Closed as stale.