1 // Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
2 //  This source code is licensed under both the GPLv2 (found in the
3 //  COPYING file in the root directory) and Apache 2.0 License
4 //  (found in the LICENSE.Apache file in the root directory).
5 
6 #pragma once
7 
8 #ifndef ROCKSDB_LITE
9 
10 #include <stack>
11 #include <string>
12 #include <unordered_map>
13 #include <vector>
14 
15 #include "db/write_callback.h"
16 #include "rocksdb/db.h"
17 #include "rocksdb/slice.h"
18 #include "rocksdb/snapshot.h"
19 #include "rocksdb/status.h"
20 #include "rocksdb/types.h"
21 #include "rocksdb/utilities/transaction.h"
22 #include "rocksdb/utilities/optimistic_transaction_db.h"
23 #include "rocksdb/utilities/write_batch_with_index.h"
24 #include "utilities/transactions/transaction_base.h"
25 #include "utilities/transactions/transaction_util.h"
26 
27 namespace ROCKSDB_NAMESPACE {
28 
29 class OptimisticTransaction : public TransactionBaseImpl {
30  public:
31   OptimisticTransaction(OptimisticTransactionDB* db,
32                         const WriteOptions& write_options,
33                         const OptimisticTransactionOptions& txn_options);
34   // No copying allowed
35   OptimisticTransaction(const OptimisticTransaction&) = delete;
36   void operator=(const OptimisticTransaction&) = delete;
37 
38   virtual ~OptimisticTransaction();
39 
40   void Reinitialize(OptimisticTransactionDB* txn_db,
41                     const WriteOptions& write_options,
42                     const OptimisticTransactionOptions& txn_options);
43 
44   Status Prepare() override;
45 
46   Status Commit() override;
47 
48   Status Rollback() override;
49 
50   Status SetName(const TransactionName& name) override;
51 
52  protected:
53   Status TryLock(ColumnFamilyHandle* column_family, const Slice& key,
54                  bool read_only, bool exclusive, const bool do_validate = true,
55                  const bool assume_tracked = false) override;
56 
57  private:
58   ROCKSDB_FIELD_UNUSED OptimisticTransactionDB* const txn_db_;
59 
60   friend class OptimisticTransactionCallback;
61 
62   void Initialize(const OptimisticTransactionOptions& txn_options);
63 
64   // Returns OK if it is safe to commit this transaction.  Returns Status::Busy
65   // if there are read or write conflicts that would prevent us from committing
66   // OR if we can not determine whether there would be any such conflicts.
67   //
68   // Should only be called on writer thread.
69   Status CheckTransactionForConflicts(DB* db);
70 
71   void Clear() override;
72 
UnlockGetForUpdate(ColumnFamilyHandle *,const Slice &)73   void UnlockGetForUpdate(ColumnFamilyHandle* /* unused */,
74                           const Slice& /* unused */) override {
75     // Nothing to unlock.
76   }
77 
78   Status CommitWithSerialValidate();
79 
80   Status CommitWithParallelValidate();
81 };
82 
83 // Used at commit time to trigger transaction validation
84 class OptimisticTransactionCallback : public WriteCallback {
85  public:
OptimisticTransactionCallback(OptimisticTransaction * txn)86   explicit OptimisticTransactionCallback(OptimisticTransaction* txn)
87       : txn_(txn) {}
88 
Callback(DB * db)89   Status Callback(DB* db) override {
90     return txn_->CheckTransactionForConflicts(db);
91   }
92 
AllowWriteBatching()93   bool AllowWriteBatching() override { return false; }
94 
95  private:
96   OptimisticTransaction* txn_;
97 };
98 
99 }  // namespace ROCKSDB_NAMESPACE
100 
101 #endif  // ROCKSDB_LITE
102