go-gorm / sharding

High performance table sharding plugin for Gorm.
MIT License
276 stars 60 forks source link

Occur DATA RACE when use sharding in concurrency #96

Closed liangjunmo closed 1 year ago

liangjunmo commented 1 year ago

GORM Playground Link

https://github.com/go-gorm/playground/pull/567

Description

Use go-gorm/sharding in concurrency, occur DATA RACE sometimes on production environment.

The code below may occur DATA RACE:

func (s *Sharding) switchConn(db *gorm.DB) {
    // Support ignore sharding in some case, like:
    // When DoubleWrite is enabled, we need to query database schema
    // information by table name during the migration.
    if _, ok := db.Get(ShardingIgnoreStoreKey); !ok {
        s.ConnPool = &ConnPool{ConnPool: db.Statement.ConnPool, sharding: s}
        db.Statement.ConnPool = s.ConnPool
    }
}

Update:

func (s *Sharding) switchConn(db *gorm.DB) {
    // Support ignore sharding in some case, like:
    // When DoubleWrite is enabled, we need to query database schema
    // information by table name during the migration.
    if _, ok := db.Get(ShardingIgnoreStoreKey); !ok {
        s.mutex.Lock()
        if db.Statement.ConnPool != nil {
            if _, ok := db.Statement.ConnPool.(ConnPool); !ok {
                db.Statement.ConnPool = &ConnPool{ConnPool: db.Statement.ConnPool, sharding: s}
            }
        }
        s.mutex.Unlock()
    }
}
liangjunmo commented 1 year ago

@hyperphoton Could you please check this issue?

shockerli commented 1 year ago

同遇到问题,期望能解决。如不需要连接切换的场景,可如下方式临时解决:

db.Statement.Settings.Store(sharding.ShardingIgnoreStoreKey, 1)