Add external transaction support to allow Casbin and GORM to share a single DB transaction by Copilot · Pull Request #1707 · apache/casbin · GitHub
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions enforcer_transactional.go
1 change: 1 addition & 0 deletions transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ type Transaction struct {
rolledBack bool // Whether the transaction has been rolled back.
startTime time.Time // Transaction start timestamp.
mutex sync.RWMutex // Protects transaction state.
isExternal bool // Whether the DB transaction is managed externally.
}

// AddPolicy adds a policy within the transaction.
Expand Down
30 changes: 19 additions & 11 deletions transaction_commit.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,10 @@ func (tx *Transaction) Commit() error {

// If no operations, just commit the database transaction and clear state.
if !tx.buffer.HasOperations() {
if err := tx.txContext.Commit(); err != nil {
return err
if !tx.isExternal {
if err := tx.txContext.Commit(); err != nil {
return err
}
}
tx.committed = true
tx.enforcer.activeTransactions.Delete(tx.id)
Expand All @@ -71,16 +73,20 @@ func (tx *Transaction) Commit() error {

// Phase 1: Apply all buffered operations to the database
if err := tx.applyOperationsToDatabase(); err != nil {
// Rollback database transaction on failure.
_ = tx.txContext.Rollback()
// Rollback database transaction on failure (only when managing our own transaction).
if !tx.isExternal {
_ = tx.txContext.Rollback()
}
tx.enforcer.activeTransactions.Delete(tx.id)
return err
}

// Commit database transaction.
if err := tx.txContext.Commit(); err != nil {
tx.enforcer.activeTransactions.Delete(tx.id)
return err
// Commit database transaction (only when managing our own transaction).
if !tx.isExternal {
if err := tx.txContext.Commit(); err != nil {
tx.enforcer.activeTransactions.Delete(tx.id)
return err
}
}

// Phase 2: Apply changes to the in-memory model
Expand Down Expand Up @@ -120,9 +126,11 @@ func (tx *Transaction) Rollback() error {
return errors.New("transaction already rolled back")
}

// Rollback database transaction.
if err := tx.txContext.Rollback(); err != nil {
return err
// Rollback database transaction (only when managing our own transaction).
if !tx.isExternal {
if err := tx.txContext.Rollback(); err != nil {
return err
}
}

tx.rolledBack = true
Expand Down
170 changes: 170 additions & 0 deletions transaction_test.go
Loading