diff --git a/src/concurrency/timestamp_ordering_transaction_manager.cpp b/src/concurrency/timestamp_ordering_transaction_manager.cpp index 3a39ccc8877..119f48ef25a 100644 --- a/src/concurrency/timestamp_ordering_transaction_manager.cpp +++ b/src/concurrency/timestamp_ordering_transaction_manager.cpp @@ -613,6 +613,14 @@ ResultType TimestampOrderingTransactionManager::CommitTransaction( gc_object_set->emplace_back(database_oid, table_oid, index_oid); } + // see if we can end early + if (!current_txn->IsWritten()) { + LOG_TRACE("Transaction not yet written, ending transaction."); + log_manager.StopLogging(); + EndTransaction(current_txn); + return ResultType::SUCCESS; + } + // install everything. // 1. install a new version for update operations; // 2. install an empty version for delete operations; diff --git a/src/concurrency/transaction_context.cpp b/src/concurrency/transaction_context.cpp index 535ba703137..83f3a734d3c 100644 --- a/src/concurrency/transaction_context.cpp +++ b/src/concurrency/transaction_context.cpp @@ -48,22 +48,24 @@ namespace concurrency { * i : insert */ -TransactionContext::TransactionContext(const size_t thread_id, +TransactionContext::TransactionContext(bool read_only, const size_t thread_id, const IsolationLevelType isolation, const cid_t &read_id) { - Init(thread_id, isolation, read_id); + Init(read_only, thread_id, isolation, read_id); } -TransactionContext::TransactionContext(const size_t thread_id, +TransactionContext::TransactionContext(bool read_only, const size_t thread_id, const IsolationLevelType isolation, const cid_t &read_id, const cid_t &commit_id) { - Init(thread_id, isolation, read_id, commit_id); + Init(read_only, thread_id, isolation, read_id, commit_id); } -void TransactionContext::Init(const size_t thread_id, +void TransactionContext::Init(bool read_only, const size_t thread_id, const IsolationLevelType isolation, const cid_t &read_id, const cid_t &commit_id) { + read_only_ = read_only; + read_id_ = read_id; // commit id can be set at a transaction's commit phase. diff --git a/src/concurrency/transaction_manager.cpp b/src/concurrency/transaction_manager.cpp index d3171213e32..e2f9bcbccfb 100644 --- a/src/concurrency/transaction_manager.cpp +++ b/src/concurrency/transaction_manager.cpp @@ -32,7 +32,7 @@ ConflictAvoidanceType TransactionManager::conflict_avoidance_ = ConflictAvoidanceType::ABORT; TransactionContext *TransactionManager::BeginTransaction( - const size_t thread_id, const IsolationLevelType type, bool read_only) { + bool read_only, const size_t thread_id, const IsolationLevelType type) { TransactionContext *txn = nullptr; if (type == IsolationLevelType::SNAPSHOT) { @@ -45,9 +45,10 @@ TransactionContext *TransactionManager::BeginTransaction( cid_t commit_id = EpochManagerFactory::GetInstance().EnterEpoch( thread_id, TimestampType::COMMIT); - txn = new TransactionContext(thread_id, type, read_id, commit_id); + txn = new TransactionContext(read_only, thread_id, type, read_id, + commit_id); } else { - txn = new TransactionContext(thread_id, type, read_id); + txn = new TransactionContext(read_only, thread_id, type, read_id); } } else { @@ -58,11 +59,7 @@ TransactionContext *TransactionManager::BeginTransaction( // transaction processing with decentralized epoch manager cid_t read_id = EpochManagerFactory::GetInstance().EnterEpoch( thread_id, TimestampType::READ); - txn = new TransactionContext(thread_id, type, read_id); - } - - if (read_only) { - txn->SetReadOnly(); + txn = new TransactionContext(read_only, thread_id, type, read_id); } txn->SetTimestamp(function::DateFunctions::Now()); diff --git a/src/include/concurrency/transaction_context.h b/src/include/concurrency/transaction_context.h index 511e0bd38f7..c23ab1d59c9 100644 --- a/src/include/concurrency/transaction_context.h +++ b/src/include/concurrency/transaction_context.h @@ -44,11 +44,12 @@ class TransactionContext : public Printable { TransactionContext(TransactionContext const &) = delete; public: - TransactionContext(const size_t thread_id, const IsolationLevelType isolation, - const cid_t &read_id); + TransactionContext(bool read_only, const size_t thread_id, + const IsolationLevelType isolation, const cid_t &read_id); - TransactionContext(const size_t thread_id, const IsolationLevelType isolation, - const cid_t &read_id, const cid_t &commit_id); + TransactionContext(bool read_only, const size_t thread_id, + const IsolationLevelType isolation, const cid_t &read_id, + const cid_t &commit_id); /** * @brief Destroys the object. @@ -56,13 +57,14 @@ class TransactionContext : public Printable { ~TransactionContext() = default; private: - void Init(const size_t thread_id, const IsolationLevelType isolation, - const cid_t &read_id) { - Init(thread_id, isolation, read_id, read_id); + void Init(bool read_only, const size_t thread_id, + const IsolationLevelType isolation, const cid_t &read_id) { + Init(read_only, thread_id, isolation, read_id, read_id); } - void Init(const size_t thread_id, const IsolationLevelType isolation, - const cid_t &read_id, const cid_t &commit_id); + void Init(bool read_only, const size_t thread_id, + const IsolationLevelType isolation, const cid_t &read_id, + const cid_t &commit_id); public: //===--------------------------------------------------------------------===// @@ -264,12 +266,11 @@ class TransactionContext : public Printable { } /** - * @brief mark this context as read only + * @brief Determines if already written. * + * @return True if already written, False otherwise. */ - void SetReadOnly() { - read_only_ = true; - } + bool IsWritten() const { return is_written_; } /** * @brief Gets the isolation level. diff --git a/src/include/concurrency/transaction_manager.h b/src/include/concurrency/transaction_manager.h index a1f17533a6d..e15eb4b6d33 100644 --- a/src/include/concurrency/transaction_manager.h +++ b/src/include/concurrency/transaction_manager.h @@ -219,13 +219,19 @@ class TransactionManager { current_txn->SetResult(result); } + TransactionContext *BeginTransaction() { return BeginTransaction(false); } + + TransactionContext *BeginTransaction(const size_t thread_id) { + return BeginTransaction(false, thread_id, isolation_level_); + } + TransactionContext *BeginTransaction(const IsolationLevelType type) { - return BeginTransaction(0, type, false); + return BeginTransaction(false, 0, type); } - TransactionContext *BeginTransaction(const size_t thread_id = 0, - const IsolationLevelType type = isolation_level_, - bool read_only = false); + TransactionContext *BeginTransaction( + bool read_only, const size_t thread_id = 0, + const IsolationLevelType type = isolation_level_); /** * @brief Ends a transaction. diff --git a/test/executor/copy_test.cpp b/test/executor/copy_test.cpp index 9b9291f4111..86d7252525c 100644 --- a/test/executor/copy_test.cpp +++ b/test/executor/copy_test.cpp @@ -93,6 +93,7 @@ TEST_F(CopyTests, Copying) { std::vector result; TestingSQLUtil::counter_.store(1); + traffic_cop.SetStatement(statement); executor::ExecutionResult status = traffic_cop.ExecuteHelper( statement->GetPlanTree(), params, result, result_format); diff --git a/test/include/concurrency/testing_transaction_util.h b/test/include/concurrency/testing_transaction_util.h index d7bb919a0f3..4fe3cb9df79 100644 --- a/test/include/concurrency/testing_transaction_util.h +++ b/test/include/concurrency/testing_transaction_util.h @@ -242,7 +242,8 @@ class TransactionThread { if (cur_seq == 0) { if (schedule->declared_ro == true) { /** starts a read only transaction*/ - txn = txn_manager->BeginTransaction(0, IsolationLevelType::SNAPSHOT, true); + txn = txn_manager->BeginTransaction(true, 0, + IsolationLevelType::SNAPSHOT); } else { txn = txn_manager->BeginTransaction(); }