From 16f8969f5a7d554f1789a2ab358ed6b97a3001f5 Mon Sep 17 00:00:00 2001
From: Vladimir Davydov <vdavydov@tarantool.org>
Date: Tue, 10 Jan 2023 17:22:41 +0300
Subject: [PATCH] txn: drop TXN_CONFLICTED transaction status

The status isn't used anywhere - to set the proper error when an aborted
transaction is attempted to be used, we check out transaction flags
(TXN_IS_CONFLICTED, TXN_IS_ABORTED_BY_YIELD, TXN_IS_ABORTED_BY_TIMEOUT).
Let's use TXN_ABORTED instead.

While we are at it, also set the transaction status to TXN_ABORTED when
a transaction is aborted by yield or timeout and use it instead of
checking flags where appropriate, since it's more convenient.

Follow-up #8123

NO_DOC=code cleanup
NO_TEST=code cleanup
NO_CHANGELOG=code cleanup
---
 src/box/memtx_tx.c |  4 ++--
 src/box/txn.c      |  7 ++++---
 src/box/txn.h      | 17 +++--------------
 3 files changed, 9 insertions(+), 19 deletions(-)

diff --git a/src/box/memtx_tx.c b/src/box/memtx_tx.c
index 23741efab4..52cd27bed0 100644
--- a/src/box/memtx_tx.c
+++ b/src/box/memtx_tx.c
@@ -532,7 +532,7 @@ memtx_tx_abort_all_for_ddl(struct txn *ddl_owner)
 		if (to_be_aborted->status != TXN_INPROGRESS &&
 		    to_be_aborted->status != TXN_IN_READ_VIEW)
 			continue;
-		to_be_aborted->status = TXN_CONFLICTED;
+		to_be_aborted->status = TXN_ABORTED;
 		txn_set_flags(to_be_aborted, TXN_IS_CONFLICTED);
 		say_warn("Transaction committing DDL (id=%lld) has aborted "
 			 "another TX (id=%lld)", (long long) ddl_owner->id,
@@ -655,7 +655,7 @@ memtx_tx_handle_conflict(struct txn *breaker, struct txn *victim)
 		/* Mark as conflicted. */
 		if (victim->status == TXN_IN_READ_VIEW)
 			rlist_del(&victim->in_read_view_txs);
-		victim->status = TXN_CONFLICTED;
+		victim->status = TXN_ABORTED;
 		txn_set_flags(victim, TXN_IS_CONFLICTED);
 	}
 }
diff --git a/src/box/txn.c b/src/box/txn.c
index ae5196236c..1d008368aa 100644
--- a/src/box/txn.c
+++ b/src/box/txn.c
@@ -593,7 +593,7 @@ txn_begin_stmt(struct txn *txn, struct space *space, uint16_t type)
 
 	if (txn->status == TXN_IN_READ_VIEW) {
 		rlist_del(&txn->in_read_view_txs);
-		txn->status = TXN_CONFLICTED;
+		txn->status = TXN_ABORTED;
 		txn_set_flags(txn, TXN_IS_CONFLICTED);
 	}
 
@@ -1549,6 +1549,7 @@ txn_on_timeout(ev_loop *loop, ev_timer *watcher, int revents)
 	(void) revents;
 	struct txn *txn = (struct txn *)watcher->data;
 	txn_rollback_to_svp(txn, NULL);
+	txn->status = TXN_ABORTED;
 	txn_set_flags(txn, TXN_IS_ABORTED_BY_TIMEOUT);
 }
 
@@ -1576,9 +1577,9 @@ txn_on_yield(struct trigger *trigger, void *event)
 	(void) event;
 	struct txn *txn = in_txn();
 	assert(txn != NULL);
-	enum txn_flag flags = TXN_CAN_YIELD | TXN_IS_ABORTED_BY_YIELD;
-	if (!txn_has_any_of_flags(txn, flags)) {
+	if (txn->status != TXN_ABORTED && !txn_has_flag(txn, TXN_CAN_YIELD)) {
 		txn_rollback_to_svp(txn, NULL);
+		txn->status = TXN_ABORTED;
 		txn_set_flags(txn, TXN_IS_ABORTED_BY_YIELD);
 		say_warn("Transaction has been aborted by a fiber yield");
 		return 0;
diff --git a/src/box/txn.h b/src/box/txn.h
index 55807281ea..5aecfd55dc 100644
--- a/src/box/txn.h
+++ b/src/box/txn.h
@@ -217,10 +217,6 @@ enum txn_status {
 	 * The TX have passed conflict checks and is ready to be committed.
 	 */
 	TXN_PREPARED,
-	/**
-	 * The TX was aborted when other TX was committed due to conflict.
-	 */
-	TXN_CONFLICTED,
 	/**
 	 * The TX was read_only, has a conflict and was sent to read view.
 	 * Read-only and does not participate in conflict resolution ever more.
@@ -233,7 +229,8 @@ enum txn_status {
 	 */
 	TXN_COMMITTED,
 	/**
-	 * The TX was aborted.
+	 * The TX was aborted, either explicitly, by box.rollback(), or
+	 * automatically, by conflict or timeout.
 	 */
 	TXN_ABORTED,
 };
@@ -547,12 +544,6 @@ txn_has_flag(const struct txn *txn, enum txn_flag flag)
 	return (txn->flags & flag) != 0;
 }
 
-static inline bool
-txn_has_any_of_flags(struct txn *txn, unsigned int flags)
-{
-	return (txn->flags & flags) != 0;
-}
-
 static inline void
 txn_set_flags(struct txn *txn, unsigned int flags)
 {
@@ -587,9 +578,7 @@ txn_flags_to_error_code(struct txn *txn)
 static inline int
 txn_check_can_continue(struct txn *txn)
 {
-	unsigned int flags = TXN_IS_CONFLICTED | TXN_IS_ABORTED_BY_YIELD |
-			     TXN_IS_ABORTED_BY_TIMEOUT;
-	if (txn_has_any_of_flags(txn, flags)) {
+	if (txn->status == TXN_ABORTED) {
 		diag_set(ClientError, txn_flags_to_error_code(txn));
 		return -1;
 	}
-- 
GitLab