]> git.proxmox.com Git - ceph.git/blame - ceph/src/rocksdb/utilities/transactions/optimistic_transaction_impl.cc
bump version to 12.2.12-pve1
[ceph.git] / ceph / src / rocksdb / utilities / transactions / optimistic_transaction_impl.cc
CommitLineData
7c673cae
FG
1// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
2// This source code is licensed under the BSD-style license found in the
3// LICENSE file in the root directory of this source tree. An additional grant
4// of patent rights can be found in the PATENTS file in the same directory.
5
6#ifndef ROCKSDB_LITE
7
8#include "utilities/transactions/optimistic_transaction_impl.h"
9
10#include <algorithm>
11#include <string>
12#include <vector>
13
14#include "db/column_family.h"
15#include "db/db_impl.h"
16#include "rocksdb/comparator.h"
17#include "rocksdb/db.h"
18#include "rocksdb/status.h"
19#include "rocksdb/utilities/optimistic_transaction_db.h"
20#include "util/string_util.h"
21#include "utilities/transactions/transaction_util.h"
22
23namespace rocksdb {
24
25struct WriteOptions;
26
27OptimisticTransactionImpl::OptimisticTransactionImpl(
28 OptimisticTransactionDB* txn_db, const WriteOptions& write_options,
29 const OptimisticTransactionOptions& txn_options)
30 : TransactionBaseImpl(txn_db->GetBaseDB(), write_options), txn_db_(txn_db) {
31 Initialize(txn_options);
32}
33
34void OptimisticTransactionImpl::Initialize(
35 const OptimisticTransactionOptions& txn_options) {
36 if (txn_options.set_snapshot) {
37 SetSnapshot();
38 }
39}
40
41void OptimisticTransactionImpl::Reinitialize(
42 OptimisticTransactionDB* txn_db, const WriteOptions& write_options,
43 const OptimisticTransactionOptions& txn_options) {
44 TransactionBaseImpl::Reinitialize(txn_db->GetBaseDB(), write_options);
45 Initialize(txn_options);
46}
47
48OptimisticTransactionImpl::~OptimisticTransactionImpl() {
49}
50
51void OptimisticTransactionImpl::Clear() {
52 TransactionBaseImpl::Clear();
53}
54
55Status OptimisticTransactionImpl::Prepare() {
56 return Status::InvalidArgument(
57 "Two phase commit not supported for optimistic transactions.");
58}
59
60Status OptimisticTransactionImpl::Commit() {
61 // Set up callback which will call CheckTransactionForConflicts() to
62 // check whether this transaction is safe to be committed.
63 OptimisticTransactionCallback callback(this);
64
65 DBImpl* db_impl = dynamic_cast<DBImpl*>(db_->GetRootDB());
66 if (db_impl == nullptr) {
67 // This should only happen if we support creating transactions from
68 // a StackableDB and someone overrides GetRootDB().
69 return Status::InvalidArgument(
70 "DB::GetRootDB() returned an unexpected DB class");
71 }
72
73 Status s = db_impl->WriteWithCallback(
74 write_options_, GetWriteBatch()->GetWriteBatch(), &callback);
75
76 if (s.ok()) {
77 Clear();
78 }
79
80 return s;
81}
82
83Status OptimisticTransactionImpl::Rollback() {
84 Clear();
85 return Status::OK();
86}
87
88// Record this key so that we can check it for conflicts at commit time.
89//
90// 'exclusive' is unused for OptimisticTransaction.
91Status OptimisticTransactionImpl::TryLock(ColumnFamilyHandle* column_family,
92 const Slice& key, bool read_only,
93 bool exclusive, bool untracked) {
94 if (untracked) {
95 return Status::OK();
96 }
97 uint32_t cfh_id = GetColumnFamilyID(column_family);
98
99 SetSnapshotIfNeeded();
100
101 SequenceNumber seq;
102 if (snapshot_) {
103 seq = snapshot_->GetSequenceNumber();
104 } else {
105 seq = db_->GetLatestSequenceNumber();
106 }
107
108 std::string key_str = key.ToString();
109
110 TrackKey(cfh_id, key_str, seq, read_only, exclusive);
111
112 // Always return OK. Confilct checking will happen at commit time.
113 return Status::OK();
114}
115
116// Returns OK if it is safe to commit this transaction. Returns Status::Busy
117// if there are read or write conflicts that would prevent us from committing OR
118// if we can not determine whether there would be any such conflicts.
119//
120// Should only be called on writer thread in order to avoid any race conditions
121// in detecting write conflicts.
122Status OptimisticTransactionImpl::CheckTransactionForConflicts(DB* db) {
123 Status result;
124
125 assert(dynamic_cast<DBImpl*>(db) != nullptr);
126 auto db_impl = reinterpret_cast<DBImpl*>(db);
127
128 // Since we are on the write thread and do not want to block other writers,
129 // we will do a cache-only conflict check. This can result in TryAgain
130 // getting returned if there is not sufficient memtable history to check
131 // for conflicts.
132 return TransactionUtil::CheckKeysForConflicts(db_impl, GetTrackedKeys(),
133 true /* cache_only */);
134}
135
136Status OptimisticTransactionImpl::SetName(const TransactionName& name) {
137 return Status::InvalidArgument("Optimistic transactions cannot be named.");
138}
139
140} // namespace rocksdb
141
142#endif // ROCKSDB_LITE