casbin / gorm-adapter

GORM adapter for Casbin, see extended version of GORM Adapter Ex at: https://github.com/casbin/gorm-adapter-ex

Home Page:https://github.com/casbin/casbin

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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.