# Copyright (c) reifydb.com 2025
# This file is licensed under the AGPL-3.0-or-later

# This file includes and modifies code from the toydb project (https://github.com/erikgrinaker/toydb),
# originally licensed under the Apache License, Version 2.0.
# Original copyright:
#   Copyright (c) 2024 Erik Grinaker
#
# The original Apache License can be found at:
#   http://www.apache.org/licenses/LICENSE-2.0

# Tests that transaction rollback properly rolls back uncommitted writes
# allowing other concurrent transactions to write the keys.

import 1 a=0 b=0 c=0 d=0
---
ok

# t2 will be rolled back. t1 and t3 are concurrent transactions.
t1: begin
t2: begin
t3: begin
---
ok

t1: set a=1
t2: set b=2
t2: remove c
t3: set d=3
---
ok

dump
---
mvcc:NextVersion → 5 ["\x00" → "\x05"]
mvcc:TxActive(2) → "" ["\x01\x00\x00\x00\x00\x00\x00\x00\x02" → ""]
mvcc:TxActive(3) → "" ["\x01\x00\x00\x00\x00\x00\x00\x00\x03" → ""]
mvcc:TxActive(4) → "" ["\x01\x00\x00\x00\x00\x00\x00\x00\x04" → ""]
mvcc:TxActiveSnapshot(3) → {2} ["\x02\x00\x00\x00\x00\x00\x00\x00\x03" → "\x01\x02"]
mvcc:TxActiveSnapshot(4) → {2,3} ["\x02\x00\x00\x00\x00\x00\x00\x00\x04" → "\x02\x02\x03"]
mvcc:TxWrite(2, "a") → "" ["\x03\x00\x00\x00\x00\x00\x00\x00\x02a\x00\x00" → ""]
mvcc:TxWrite(3, "b") → "" ["\x03\x00\x00\x00\x00\x00\x00\x00\x03b\x00\x00" → ""]
mvcc:TxWrite(3, "c") → "" ["\x03\x00\x00\x00\x00\x00\x00\x00\x03c\x00\x00" → ""]
mvcc:TxWrite(4, "d") → "" ["\x03\x00\x00\x00\x00\x00\x00\x00\x04d\x00\x00" → ""]
mvcc:Version("a", 1) → "0" ["\x04a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" → "\x01\x010"]
mvcc:Version("a", 2) → "1" ["\x04a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02" → "\x01\x011"]
mvcc:Version("b", 1) → "0" ["\x04b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" → "\x01\x010"]
mvcc:Version("b", 3) → "2" ["\x04b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03" → "\x01\x012"]
mvcc:Version("c", 1) → "0" ["\x04c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" → "\x01\x010"]
mvcc:Version("c", 3) → None ["\x04c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03" → "\x00"]
mvcc:Version("d", 1) → "0" ["\x04d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" → "\x01\x010"]
mvcc:Version("d", 4) → "3" ["\x04d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04" → "\x01\x013"]

# Both t1 and t3 will conflict with t2.
t1: !set b=1
t3: !set c=3
---
t1: Error: transaction serialization conflict occurred, retry transaction
t3: Error: transaction serialization conflict occurred, retry transaction

# When t2 is rolled back, none of its writes will be visible, and t1 and t3 can
# perform their writes and successfully commit.
t2: rollback [ops]
---
t2: engine remove mvcc:Version("b", 3) ["\x04b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03"]
t2: engine remove mvcc:TxWrite(3, "b") ["\x03\x00\x00\x00\x00\x00\x00\x00\x03b\x00\x00"]
t2: engine remove mvcc:Version("c", 3) ["\x04c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03"]
t2: engine remove mvcc:TxWrite(3, "c") ["\x03\x00\x00\x00\x00\x00\x00\x00\x03c\x00\x00"]
t2: engine remove mvcc:TxActive(3) ["\x01\x00\x00\x00\x00\x00\x00\x00\x03"]

t4: begin readonly
t4: scan
---
t4: "a" → "0"
t4: "b" → "0"
t4: "c" → "0"
t4: "d" → "0"

t1: set b=1
t1: commit
t3: set c=3
t3: commit
---
ok

t5: begin readonly
t5: scan
---
t5: "a" → "1"
t5: "b" → "1"
t5: "c" → "3"
t5: "d" → "3"

dump
---
mvcc:NextVersion → 5 ["\x00" → "\x05"]
mvcc:TxActiveSnapshot(3) → {2} ["\x02\x00\x00\x00\x00\x00\x00\x00\x03" → "\x01\x02"]
mvcc:TxActiveSnapshot(4) → {2,3} ["\x02\x00\x00\x00\x00\x00\x00\x00\x04" → "\x02\x02\x03"]
mvcc:Version("a", 1) → "0" ["\x04a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" → "\x01\x010"]
mvcc:Version("a", 2) → "1" ["\x04a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02" → "\x01\x011"]
mvcc:Version("b", 1) → "0" ["\x04b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" → "\x01\x010"]
mvcc:Version("b", 2) → "1" ["\x04b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02" → "\x01\x011"]
mvcc:Version("c", 1) → "0" ["\x04c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" → "\x01\x010"]
mvcc:Version("c", 4) → "3" ["\x04c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04" → "\x01\x013"]
mvcc:Version("d", 1) → "0" ["\x04d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" → "\x01\x010"]
mvcc:Version("d", 4) → "3" ["\x04d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04" → "\x01\x013"]
