new-lock-table maxlocks=10000
----

new-txn txn=txn1 ts=10,1 epoch=0 iso=read-committed
----

new-txn txn=txn2 ts=10,1 epoch=0 iso=read-committed
----

new-txn txn=txn3 ts=10,1 epoch=0 iso=serializable
----

new-txn txn=txn4 ts=10,1 epoch=0 iso=snapshot
----

new-txn txn=txn5 ts=10,1 epoch=0 iso=snapshot
----

# ------------------------------------------------------------------------------
# Test that non-locking reads from transactions that can tolerate write skew
# (RC, snapshot) do not block on exclusive locks held by other
# RC/Serializable/Snapshot transactions.
# ------------------------------------------------------------------------------

# Acquire three locks -- using serializable, snapshot, and RC transactions each.

new-request r=req1 txn=txn2 ts=10,1 spans=exclusive@a
----

acquire r=req1 k=a durability=u strength=exclusive
----
num=1
 lock: "a"
  holder: txn: 00000000-0000-0000-0000-000000000002 epoch: 0, iso: ReadCommitted, ts: 10.000000000,1, info: unrepl [(str: Exclusive seq: 0)]

new-request r=req2 txn=txn3 ts=10,1 spans=exclusive@b
----

acquire r=req1 k=a durability=u strength=exclusive
----
num=1
 lock: "a"
  holder: txn: 00000000-0000-0000-0000-000000000002 epoch: 0, iso: ReadCommitted, ts: 10.000000000,1, info: unrepl [(str: Exclusive seq: 0)]

acquire r=req2 k=b durability=u strength=exclusive
----
num=2
 lock: "a"
  holder: txn: 00000000-0000-0000-0000-000000000002 epoch: 0, iso: ReadCommitted, ts: 10.000000000,1, info: unrepl [(str: Exclusive seq: 0)]
 lock: "b"
  holder: txn: 00000000-0000-0000-0000-000000000003 epoch: 0, iso: Serializable, ts: 10.000000000,1, info: unrepl [(str: Exclusive seq: 0)]

new-request r=req3 txn=txn4 ts=10,1 spans=exclusive@c
----

acquire r=req3 k=c durability=u strength=exclusive
----
num=3
 lock: "a"
  holder: txn: 00000000-0000-0000-0000-000000000002 epoch: 0, iso: ReadCommitted, ts: 10.000000000,1, info: unrepl [(str: Exclusive seq: 0)]
 lock: "b"
  holder: txn: 00000000-0000-0000-0000-000000000003 epoch: 0, iso: Serializable, ts: 10.000000000,1, info: unrepl [(str: Exclusive seq: 0)]
 lock: "c"
  holder: txn: 00000000-0000-0000-0000-000000000004 epoch: 0, iso: Snapshot, ts: 10.000000000,1, info: unrepl [(str: Exclusive seq: 0)]

# A non-locking read from a RC transaction should not wait.
new-request r=req4 txn=txn1 ts=10,1 spans=none@a,d
----

scan r=req4
----
start-waiting: false

# A non-locking read from a snapshot transaction should not wait.

new-request r=req5 txn=txn5 ts=10,1 spans=none@a,d
----

scan r=req5
----
start-waiting: false

# ------------------------------------------------------------------------------
# Test that non-locking requests from {RC, snapshot} transactions do block on
# Intents.
# ------------------------------------------------------------------------------

clear
----
num=0

# Non-locking read from a RC txn.
new-request r=req6 txn=txn1 ts=10,1 spans=none@a
----

# Non-locking read from a snapshot txn.
new-request r=req7 txn=txn5 ts=10,1 spans=none@b
----

scan r=req6
----
start-waiting: false

scan r=req7
----
start-waiting: false

add-discovered r=req6 k=a txn=txn2
----
num=1
 lock: "a"
  holder: txn: 00000000-0000-0000-0000-000000000002 epoch: 0, iso: ReadCommitted, ts: 10.000000000,1, info: repl [Intent]

add-discovered r=req7 k=b txn=txn2
----
num=2
 lock: "a"
  holder: txn: 00000000-0000-0000-0000-000000000002 epoch: 0, iso: ReadCommitted, ts: 10.000000000,1, info: repl [Intent]
 lock: "b"
  holder: txn: 00000000-0000-0000-0000-000000000002 epoch: 0, iso: ReadCommitted, ts: 10.000000000,1, info: repl [Intent]

scan r=req6
----
start-waiting: true

guard-state r=req6
----
new: state=waitFor txn=txn2 key="a" held=true guard-strength=None

scan r=req7
----
start-waiting: true

guard-state r=req7
----
new: state=waitFor txn=txn2 key="b" held=true guard-strength=None

# ------------------------------------------------------------------------------
# Test that exclusive locks held by {RC,snapshot} transactions do not block
# non-locking reads from serializable transactions. {RC, snapshot} transactions
# can tolerate write skew, so such blocking is of no use.
# ------------------------------------------------------------------------------

clear
----
num=0

# RC txn.
new-request r=req8 txn=txn1 ts=10,1 spans=exclusive@a
----

acquire r=req8 k=a durability=u strength=exclusive
----
num=1
 lock: "a"
  holder: txn: 00000000-0000-0000-0000-000000000001 epoch: 0, iso: ReadCommitted, ts: 10.000000000,1, info: unrepl [(str: Exclusive seq: 0)]

# Snapshot txn.
new-request r=req9 txn=txn5 ts=10,1 spans=exclusive@b
----

acquire r=req9 k=b durability=u strength=exclusive
----
num=2
 lock: "a"
  holder: txn: 00000000-0000-0000-0000-000000000001 epoch: 0, iso: ReadCommitted, ts: 10.000000000,1, info: unrepl [(str: Exclusive seq: 0)]
 lock: "b"
  holder: txn: 00000000-0000-0000-0000-000000000005 epoch: 0, iso: Snapshot, ts: 10.000000000,1, info: unrepl [(str: Exclusive seq: 0)]

# Non-locking read from a serializable transaction.
new-request r=req10 txn=txn2 ts=10,1 spans=none@a
----

scan r=req10
----
start-waiting: false
