Browse Source

SqlServer->SQLServer, combine select+order by

pull/467/head
徐云金YunjinXu 2 years ago
parent
commit
17b3b1256b
  1. 4
      client/dtmcli/consts.go
  2. 4
      client/dtmcli/dtmimp/consts.go
  3. 2
      client/dtmcli/dtmimp/db_special.go
  4. 4
      client/dtmcli/dtmimp/utils.go
  5. 6
      dtmsvr/config/config.go
  6. 18
      dtmsvr/storage/sql/sql.go
  7. 2
      dtmutil/db.go
  8. 2
      test/main_test.go

4
client/dtmcli/consts.go

@ -35,8 +35,8 @@ const (
DBTypeMysql = dtmimp.DBTypeMysql
// DBTypePostgres const for driver postgres
DBTypePostgres = dtmimp.DBTypePostgres
// DBTypeSqlServer const for driver SqlServer
DBTypeSqlServer = dtmimp.DBTypeSqlServer
// DBTypeSQLServer const for driver SQLServer
DBTypeSQLServer = dtmimp.DBTypeSQLServer
)
// MapSuccess HTTP result of SUCCESS

4
client/dtmcli/dtmimp/consts.go

@ -36,8 +36,8 @@ const (
DBTypeMysql = "mysql"
// DBTypePostgres const for driver postgres
DBTypePostgres = "postgres"
// DBTypeSqlServer const for driver SqlServer
DBTypeSqlServer = "sqlserver"
// DBTypeSQLServer const for driver SQLServer
DBTypeSQLServer = "sqlserver"
// DBTypeRedis const for driver redis
DBTypeRedis = "redis"
// Jrpc const for json-rpc

2
client/dtmcli/dtmimp/db_special.go

@ -96,7 +96,7 @@ func (*sqlserverDBSpecial) GetXaSQL(command string, xid string) string {
return ""
}
func init() {
dbSpecials[DBTypeSqlServer] = &sqlserverDBSpecial{}
dbSpecials[DBTypeSQLServer] = &sqlserverDBSpecial{}
}
// GetDBSpecial get DBSpecial for currentDBType

4
client/dtmcli/dtmimp/utils.go

@ -229,13 +229,13 @@ func GetDsn(conf DBConf) string {
"postgres": fmt.Sprintf("host=%s user=%s password=%s dbname='%s' search_path=%s port=%d sslmode=disable",
host, conf.User, conf.Password, conf.Db, conf.Schema, conf.Port),
// sqlserver://sa:mypass@localhost:1234?database=master&connection+timeout=30
"sqlserver": getSqlServerConnectionString(&conf, &host),
"sqlserver": getSQLServerConnectionString(&conf, &host),
}[driver]
PanicIf(dsn == "", fmt.Errorf("unknow driver: %s", driver))
return dsn
}
func getSqlServerConnectionString(conf *DBConf, host *string) string {
func getSQLServerConnectionString(conf *DBConf, host *string) string {
query := url.Values{}
query.Add("database", conf.Db)
u := &url.URL{

6
dtmsvr/config/config.go

@ -20,8 +20,8 @@ const (
BoltDb = "boltdb"
// Postgres is postgres driver
Postgres = "postgres"
// SqlServer is SQL Server driver
SqlServer = "sqlserver"
// SQLServer is SQL Server driver
SQLServer = "sqlserver"
)
// MicroService config type for microservice based grpc
@ -67,7 +67,7 @@ type Store struct {
// IsDB checks config driver is mysql or postgres
func (s *Store) IsDB() bool {
return s.Driver == dtmcli.DBTypeMysql || s.Driver == dtmcli.DBTypePostgres || s.Driver == dtmcli.DBTypeSqlServer
return s.Driver == dtmcli.DBTypeMysql || s.Driver == dtmcli.DBTypePostgres || s.Driver == dtmcli.DBTypeSQLServer
}
// GetDBConf returns db conf info

18
dtmsvr/storage/sql/sql.go

@ -107,7 +107,7 @@ func (s *Store) LockGlobalSaveBranches(gid string, status string, branches []sto
g := &storage.TransGlobalStore{}
var dbr *gorm.DB
// sqlserver sql should be: SELECT * FROM "trans_global" with(RowLock,UpdLock) ,but gorm generates "FOR UPDATE" at the back, raw sql instead.
if conf.Store.Driver == config.SqlServer {
if conf.Store.Driver == config.SQLServer {
dbr = tx.Raw("SELECT * FROM trans_global with(RowLock,UpdLock) WHERE gid=? and status=? ORDER BY id OFFSET 0 ROW FETCH NEXT 1 ROWS ONLY ", gid, status).First(g)
} else {
dbr = tx.Clauses(clause.Locking{Strength: "UPDATE"}).Model(g).Where("gid=? and status=?", gid, status).First(g)
@ -169,16 +169,10 @@ func (s *Store) LockOneGlobalTrans(expireIn time.Duration) *storage.TransGlobalS
nextCronTime := getTimeStr(int64(expireIn / time.Second))
where := fmt.Sprintf(`next_cron_time < '%s' and status in ('prepared', 'aborting', 'submitted')`, nextCronTime)
order := map[string]string{
dtmimp.DBTypeMysql: `order by rand()`,
dtmimp.DBTypePostgres: `order by random()`,
dtmimp.DBTypeSqlServer: `order by rand()`,
}[conf.Store.Driver]
ssql := map[string]string{
dtmimp.DBTypeMysql: fmt.Sprintf(`select id from trans_global where %s %s limit 1`, where, order),
dtmimp.DBTypePostgres: fmt.Sprintf(`select id from trans_global where %s %s limit 1`, where, order),
dtmimp.DBTypeSqlServer: fmt.Sprintf(`select top 1 id from trans_global where %s %s`, where, order),
dtmimp.DBTypeMysql: fmt.Sprintf(`select id from trans_global where %s order by rand() limit 1`, where),
dtmimp.DBTypePostgres: fmt.Sprintf(`select id from trans_global where %s order by random() limit 1`, where),
dtmimp.DBTypeSQLServer: fmt.Sprintf(`select top 1 id from trans_global where %s order by rand()`, where),
}[conf.Store.Driver]
var id int64
err := db.ToSQLDB().QueryRow(ssql).Scan(&id)
@ -211,7 +205,7 @@ func (s *Store) ResetCronTime(after time.Duration, limit int64) (succeedCount in
where := map[string]string{
dtmimp.DBTypeMysql: fmt.Sprintf(`next_cron_time > '%s' and status in ('prepared', 'aborting', 'submitted') limit %d`, nextCronTime, limit),
dtmimp.DBTypePostgres: fmt.Sprintf(`id in (select id from trans_global where next_cron_time > '%s' and status in ('prepared', 'aborting', 'submitted') limit %d )`, nextCronTime, limit),
dtmimp.DBTypeSqlServer: fmt.Sprintf(`id in (select top %d id from trans_global where next_cron_time > '%s' and status in ('prepared', 'aborting', 'submitted') )`, limit, nextCronTime),
dtmimp.DBTypeSQLServer: fmt.Sprintf(`id in (select top %d id from trans_global where next_cron_time > '%s' and status in ('prepared', 'aborting', 'submitted') )`, limit, nextCronTime),
}[conf.Store.Driver]
sql := fmt.Sprintf(`UPDATE trans_global SET update_time='%s',next_cron_time='%s' WHERE %s`,
@ -329,7 +323,7 @@ func wrapError(err error) error {
}
func getTimeStr(afterSecond int64) string {
if conf.Store.Driver == config.SqlServer {
if conf.Store.Driver == config.SQLServer {
return dtmutil.GetNextTime(afterSecond).Format(time.RFC3339)
}
return dtmutil.GetNextTime(afterSecond).Format("2006-01-02 15:04:05")

2
dtmutil/db.go

@ -30,7 +30,7 @@ func getGormDialetor(driver string, dsn string) gorm.Dialector {
if driver == dtmcli.DBTypePostgres {
return postgres.Open(dsn)
}
if driver == dtmcli.DBTypeSqlServer {
if driver == dtmcli.DBTypeSQLServer {
return sqlserver.Open(dsn)
}
dtmimp.PanicIf(driver != dtmcli.DBTypeMysql, fmt.Errorf("unknown driver: %s", driver))

2
test/main_test.go

@ -53,7 +53,7 @@ func TestMain(m *testing.M) {
conf.Store.User = ""
conf.Store.Password = ""
conf.Store.Port = 6379
} else if tenv == config.SqlServer {
} else if tenv == config.SQLServer {
conf.Store.User = "sa"
conf.Store.Password = "p@ssw0rd"
conf.Store.Port = 1433

Loading…
Cancel
Save