github.com/ecodeclub/eorm@v0.0.2-0.20231001112437-dae71da914d0/internal/datasource/transaction/types.go (about) 1 // Copyright 2021 ecodeclub 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package transaction 16 17 import ( 18 "context" 19 "database/sql" 20 21 "github.com/ecodeclub/eorm/internal/errs" 22 23 "github.com/ecodeclub/eorm/internal/datasource" 24 ) 25 26 // 为了方便管理不同类型的 分布式 Tx,所以这里引入 TxType 常量来支持创建不同的 分布式Tx类型 以便提高后续引入 XA 方案的扩展性。 27 const ( 28 Delay = "delay" 29 Single = "single" 30 ) 31 32 type TxFactory interface { 33 TxOf(ctx Context, finder datasource.Finder) (datasource.Tx, error) 34 } 35 36 type Context struct { 37 TxName string 38 TxCtx context.Context 39 Opts *sql.TxOptions 40 } 41 42 type TypeKey struct{} 43 44 func UsingTxType(ctx context.Context, val string) context.Context { 45 return context.WithValue(ctx, TypeKey{}, val) 46 } 47 48 func GetCtxTypeKey(ctx context.Context) any { 49 return ctx.Value(TypeKey{}) 50 } 51 52 type TxFacade struct { 53 factory TxFactory 54 finder datasource.Finder 55 } 56 57 func NewTxFacade(ctx context.Context, finder datasource.Finder) (TxFacade, error) { 58 res := TxFacade{ 59 finder: finder, 60 } 61 switch GetCtxTypeKey(ctx).(string) { 62 case Delay: 63 res.factory = DelayTxFactory{} 64 return res, nil 65 case Single: 66 res.factory = SingleTxFactory{} 67 return res, nil 68 default: 69 return TxFacade{}, errs.ErrUnsupportedDistributedTransaction 70 } 71 } 72 73 func (t *TxFacade) BeginTx(ctx context.Context, opts *sql.TxOptions) (datasource.Tx, error) { 74 dsCtx := Context{ 75 TxCtx: ctx, 76 Opts: opts, 77 TxName: GetCtxTypeKey(ctx).(string), 78 } 79 return t.factory.TxOf(dsCtx, t.finder) 80 }