diff --git a/src/box/memtx_tx.c b/src/box/memtx_tx.c
index 23741efab4e577949da0224e891ca8fe4b8093c0..52cd27bed0570a572f4d80df5c8fe142494a418f 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 ae5196236c09f15b92c9dda3b1980ad2c85818aa..1d008368aa484af79d4fe9f8a0dd7ac1181f95d5 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 55807281ea03c9a998809c55bbebd8430625842d..5aecfd55dcad43f668741f73d8762a0fcf80d1e9 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;
 	}