casbin / gorm-adapter

GORM adapter for Casbin, see extended version of GORM Adapter Ex at: https://github.com/casbin/gorm-adapter-ex
https://github.com/casbin/casbin
Apache License 2.0
692 stars 206 forks source link

fix: fix db switch error in transaction #209

Closed weloe closed 1 year ago

weloe commented 1 year ago

test code

func TestAdapterTransactionOpertionBetweenMulDb(t *testing.T) {

    //create new database
    NewAdapter("mysql", "root:hsp@tcp(127.0.0.1:3306)/", "casbin")
    NewAdapter("mysql", "root:hsp@tcp(127.0.0.1:3306)/", "casbin2")

    dsn := "root:hsp@tcp(127.0.0.1:3306)/casbin"
    dsn2 := "root:hsp@tcp(127.0.0.1:3306)/casbin2"

    dbPool, err := InitDbResolver([]gorm.Dialector{mysql.Open(dsn), mysql.Open(dsn2)}, []string{"casbin", "casbin2"})

    if err != nil {
        panic(err)
    }

    //test independence between multi adapter
    a1 := initAdapterWithGormInstanceByMulDb(t, dbPool, "casbin", "", "casbin_rule")
    a1.AddPolicy("p", "p", []string{"t1", "t1", "t1"})

    a2 := initAdapterWithGormInstanceByMulDb(t, dbPool, "casbin2", "", "casbin_rule2")
    // add policies
    a2.AddPolicies("p", "p", [][]string{{"t2", "t2", "t2"}, {"t3", "t3", "t3"}})
    // transaction remove
    a2.RemovePolicies("p", "p", [][]string{{"t2", "t2", "t2"}, {"t3", "t3", "t3"}})

}
=== RUN   TestAdapterTransactionOpertionBetweenMulDb
2023/04/13 23:04:19 Policy: []
2023/04/13 23:04:19 Policy: [[alice data1 read] [bob data2 write] [data2_admin data2 read] [data2_admin data2 write]]
2023/04/13 23:04:19 Policy: []
2023/04/13 23:04:19 Policy: [[alice data1 read] [bob data2 write] [data2_admin data2 read] [data2_admin data2 write]]

2023/04/13 23:04:19 D:/GithubRepository/gorm-adapter/adapter.go:761 Error 1146: Table 'casbin.casbin_rule2' doesn't exist
[0.000ms] [rows:0] DELETE FROM `casbin_rule2` WHERE ptype = 'p' and v0 = 't2' and v1 = 't2' and v2 = 't2'
--- PASS: TestAdapterTransactionOpertionBetweenMulDb (0.07s)
PASS

a2.RemovePolicies() execute sql delete unexpected db's table : DELETE FROM casbin.casbin_rule2 WHERE ptype = 'p' and v0 = 't2' and v1 = 't2' and v2 = 't2' , it should be "casbin2.cabin_rule2".

First the error appeared in this pr https://github.com/casbin/gorm-adapter/pull/208#issuecomment-1505296620 , and I use DB.Clauses(dbresolver.Write) fix it

After I learn from gorm docs When using transaction, DBResolver will keep using the transaction and won’t switch to sources/replicas based on configuration

In this test, db transaction use "casbin" db ,because When using transaction, DBResolver will keep using the transaction and won’t switch to sources/replicas based on configuration, so db transaction use source "casbin" db to execute RemovePolicies() and it should be "casbin2" db

We can also use .Clauses(dbresolver.Write) to manual connection switching before every db transaction like I do in pr https://github.com/casbin/gorm-adapter/pull/208#issuecomment-1505296620 ,but to reduce the scope of the impact of modifying the code, I update NewAdapterByMulDb to compatible transaction operation.

func NewAdapterByMulDb(dbPool DbPool, dbName string, prefix string, tableName string) (*Adapter, error) {
    //change DB
    db := dbPool.switchDb(dbName)

    return NewAdapterByDBUseTableName(db, prefix, tableName)
}
casbin-bot commented 1 year ago

@tangyang9464 @JalinWang @imp2002 please review

github-actions[bot] commented 1 year ago

:tada: This PR is included in version 3.16.1 :tada:

The release is available on GitHub release

Your semantic-release bot :package::rocket: