Skip to content

Commit

Permalink
fix: initialize transactionMu correctly and ensure the transitivity o…
Browse files Browse the repository at this point in the history
…f transactionMu.
  • Loading branch information
kingzyt committed Apr 25, 2024
1 parent 15ac848 commit f941c9c
Showing 1 changed file with 4 additions and 11 deletions.
15 changes: 4 additions & 11 deletions adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ func NewAdapterByDBUseTableName(db *gorm.DB, prefix string, tableName string) (*
a := &Adapter{
tablePrefix: prefix,
tableName: tableName,
transactionMu : &sync.Mutex{},
}

a.db = db.Scopes(a.casbinRuleTable()).Session(&gorm.Session{Context: db.Statement.Context})
Expand Down Expand Up @@ -262,6 +263,7 @@ func NewFilteredAdapterByDB(db *gorm.DB, prefix string, tableName string) (*Adap
tablePrefix: prefix,
tableName: tableName,
isFiltered: true,
transactionMu : &sync.Mutex{},
}
adapter.db = db.Scopes(adapter.casbinRuleTable()).Session(&gorm.Session{Context: db.Statement.Context})

Expand Down Expand Up @@ -690,31 +692,22 @@ func (a *Adapter) AddPolicies(sec string, ptype string, rules [][]string) error

// Transaction perform a set of operations within a transaction
func (a *Adapter) Transaction(e casbin.IEnforcer, fc func(casbin.IEnforcer) error, opts ...*sql.TxOptions) error {
// ensure the transactionMu is initialized
if a.transactionMu == nil {
for a.muInitialize.CompareAndSwap(false, true) {
if a.transactionMu == nil {
a.transactionMu = &sync.Mutex{}
}
a.muInitialize.Store(false)
}
}
// lock the transactionMu to ensure the transaction is thread-safe
a.transactionMu.Lock()
defer a.transactionMu.Unlock()
var err error
oriAdapter := a.db
// reload policy from database to sync with the transaction
defer func() {
e.SetAdapter(&Adapter{db: oriAdapter})
e.SetAdapter(&Adapter{db: oriAdapter, transactionMu: a.transactionMu})
err = e.LoadPolicy()
if err != nil {
panic(err)
}
}()
copyDB := *a.db
tx := copyDB.Begin(opts...)
b := &Adapter{db: tx}
b := &Adapter{db: tx, transactionMu: a.transactionMu}
// copy enforcer to set the new adapter with transaction tx
copyEnforcer := e
copyEnforcer.SetAdapter(b)
Expand Down

0 comments on commit f941c9c

Please sign in to comment.