github.com/vescale/zgraph@v0.0.0-20230410094002-959c02d50f95/storage/resolver/txn_status.go (about) 1 // Copyright 2022 zGraph Authors. All rights reserved. 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 resolver 16 17 import ( 18 "time" 19 20 "github.com/cockroachdb/pebble" 21 "github.com/pingcap/errors" 22 "github.com/vescale/zgraph/storage/kv" 23 "github.com/vescale/zgraph/storage/mvcc" 24 ) 25 26 type TxnAction byte 27 28 const ( 29 TxnActionNone TxnAction = iota 30 TxnActionTTLExpireRollback 31 TxnActionLockNotExistRollback 32 TxnActionLockNotExistDoNothing 33 ) 34 35 type TxnStatus struct { 36 CommitVer kv.Version 37 Action TxnAction 38 } 39 40 // CheckTxnStatus checks the transaction status according to the primary key. 41 func CheckTxnStatus(db *pebble.DB, vp kv.VersionProvider, primaryKey kv.Key, startVer kv.Version) (TxnStatus, error) { 42 opt := pebble.IterOptions{LowerBound: mvcc.LockKey(primaryKey)} 43 iter := db.NewIter(&opt) 44 iter.First() 45 defer iter.Close() 46 47 if !iter.Valid() { 48 return TxnStatus{}, errors.New("txn not found") 49 } 50 51 decoder := mvcc.LockDecoder{ExpectKey: primaryKey} 52 exists, err := decoder.Decode(iter) 53 if err != nil { 54 return TxnStatus{}, err 55 } 56 57 // If the transaction lock exists means the current transaction not committed. 58 if exists && decoder.Lock.StartVer == startVer { 59 ver := vp.CurrentVersion() 60 exp := startVer + kv.Version(time.Duration(decoder.Lock.TTL)*time.Millisecond) 61 if exp < ver { 62 return TxnStatus{Action: TxnActionTTLExpireRollback}, nil 63 } 64 return TxnStatus{Action: TxnActionNone}, nil 65 } 66 67 c, exists, err := getTxnCommitInfo(iter, primaryKey, startVer) 68 if err != nil { 69 return TxnStatus{}, err 70 } 71 if exists { 72 if c.Type == mvcc.ValueTypeRollback { 73 return TxnStatus{Action: TxnActionLockNotExistRollback}, nil 74 } 75 return TxnStatus{CommitVer: c.CommitVer, Action: TxnActionLockNotExistDoNothing}, nil 76 } 77 78 return TxnStatus{}, errors.New("transaction status missing") 79 }