new-txn name=txn1 ts=10,1 epoch=0
----

new-txn name=txn2 ts=11,1 epoch=0
----

new-txn name=txn3 ts=11,1 epoch=0
----

new-txn name=txnNoWait ts=12,1 epoch=0
----

# -------------------------------------------------------------
# Prep: Txn 1 acquire locks at key k and key k2
#       Txn 2 acquire locks at key k3
#       Txn 3 begins waiting in k2's wait-queue
# -------------------------------------------------------------

new-request name=req1 txn=txn1 ts=10,0
  put key=k  value=v
  put key=k2 value=v2
----

sequence req=req1
----
[1] sequence req1: sequencing request
[1] sequence req1: acquiring latches
[1] sequence req1: scanning lock table for conflicting locks
[1] sequence req1: sequencing complete, returned guard

on-lock-acquired req=req1 key=k
----
[-] acquire lock: txn 00000001 @ ‹k›

on-lock-acquired req=req1 key=k2
----
[-] acquire lock: txn 00000001 @ ‹k2›

finish req=req1
----
[-] finish req1: finishing request

new-request name=req2 txn=txn2 ts=11,0
  put key=k3 value=v
----

sequence req=req2
----
[2] sequence req2: sequencing request
[2] sequence req2: acquiring latches
[2] sequence req2: scanning lock table for conflicting locks
[2] sequence req2: sequencing complete, returned guard

on-lock-acquired req=req2 key=k3
----
[-] acquire lock: txn 00000002 @ ‹k3›

finish req=req2
----
[-] finish req2: finishing request

new-request name=req3 txn=txn3 ts=11,0
  put key=k2 value=v
  put key=k3 value=v
----

sequence req=req3
----
[3] sequence req3: sequencing request
[3] sequence req3: acquiring latches
[3] sequence req3: scanning lock table for conflicting locks
[3] sequence req3: waiting in lock wait-queues
[3] sequence req3: lock wait-queue event: wait for txn 00000001 holding lock @ key ‹"k2"› (queuedLockingRequests: 1, queuedReaders: 0)
[3] sequence req3: pushing after 0s for: deadlock/liveness detection = true, timeout enforcement = false, priority enforcement = false, wait policy error = false
[3] sequence req3: pushing txn 00000001 to abort
[3] sequence req3: blocked on select in concurrency_test.(*cluster).PushTransaction

debug-lock-table
----
num=3
 lock: "k"
  holder: txn: 00000001-0000-0000-0000-000000000000 epoch: 0, iso: Serializable, ts: 10.000000000,0, info: unrepl [(str: Exclusive seq: 0)]
 lock: "k2"
  holder: txn: 00000001-0000-0000-0000-000000000000 epoch: 0, iso: Serializable, ts: 10.000000000,0, info: unrepl [(str: Exclusive seq: 0)]
   queued locking requests:
    active: true req: 3, strength: Intent, txn: 00000003-0000-0000-0000-000000000000
 lock: "k3"
  holder: txn: 00000002-0000-0000-0000-000000000000 epoch: 0, iso: Serializable, ts: 11.000000000,0, info: unrepl [(str: Exclusive seq: 0)]

# -------------------------------------------------------------
# Read-only request with lock timeout hits lock. The request
# raises an error.
# -------------------------------------------------------------

new-request name=reqTimeout1 txn=txnNoWait ts=12,0 lock-timeout
  get key=k
----

sequence req=reqTimeout1
----
[4] sequence reqTimeout1: sequencing request
[4] sequence reqTimeout1: acquiring latches
[4] sequence reqTimeout1: scanning lock table for conflicting locks
[4] sequence reqTimeout1: waiting in lock wait-queues
[4] sequence reqTimeout1: lock wait-queue event: wait for txn 00000001 holding lock @ key ‹"k"› (queuedLockingRequests: 0, queuedReaders: 1)
[4] sequence reqTimeout1: pushing after 0s for: deadlock/liveness detection = true, timeout enforcement = true, priority enforcement = false, wait policy error = false
[4] sequence reqTimeout1: pushing timestamp of txn 00000001 above 12.000000000,1
[4] sequence reqTimeout1: pushee not abandoned
[4] sequence reqTimeout1: conflicted with ‹00000001-0000-0000-0000-000000000000› on ‹"k"› for 0.000s
[4] sequence reqTimeout1: sequencing complete, returned error: conflicting locks on ‹"k"› [reason=lock_timeout]

# -------------------------------------------------------------
# Read-only request with lock timeout hits abandoned lock.
# The request removes the abandoned unreplicated lock and proceeds.
# -------------------------------------------------------------

on-txn-updated txn=txn1 status=committed
----
[-] update txn: committing txn1
[3] sequence req3: resolving intent ‹"k2"› for txn 00000001 with COMMITTED status
[3] sequence req3: lock wait-queue event: wait for txn 00000002 holding lock @ key ‹"k3"› (queuedLockingRequests: 1, queuedReaders: 0)
[3] sequence req3: conflicted with ‹00000001-0000-0000-0000-000000000000› on ‹"k2"› for 0.000s
[3] sequence req3: pushing after 0s for: deadlock/liveness detection = true, timeout enforcement = false, priority enforcement = false, wait policy error = false
[3] sequence req3: pushing txn 00000002 to abort
[3] sequence req3: blocked on select in concurrency_test.(*cluster).PushTransaction

sequence req=reqTimeout1
----
[5] sequence reqTimeout1: sequencing request
[5] sequence reqTimeout1: acquiring latches
[5] sequence reqTimeout1: scanning lock table for conflicting locks
[5] sequence reqTimeout1: sequencing complete, returned guard

finish req=reqTimeout1
----
[-] finish reqTimeout1: finishing request

debug-lock-table
----
num=2
 lock: "k2"
   queued locking requests:
    active: false req: 3, strength: Intent, txn: 00000003-0000-0000-0000-000000000000
 lock: "k3"
  holder: txn: 00000002-0000-0000-0000-000000000000 epoch: 0, iso: Serializable, ts: 11.000000000,0, info: unrepl [(str: Exclusive seq: 0)]
   queued locking requests:
    active: true req: 3, strength: Intent, txn: 00000003-0000-0000-0000-000000000000

# -------------------------------------------------------------
# Read-write request with lock timeout hits reservation
# holder. The request immediately raises an error instead of
# waiting for the reservation holder.
# -------------------------------------------------------------

new-request name=reqTimeout2 txn=txnNoWait ts=12,0 lock-timeout
  put key=k2 value=v4
----

sequence req=reqTimeout2
----
[6] sequence reqTimeout2: sequencing request
[6] sequence reqTimeout2: acquiring latches
[6] sequence reqTimeout2: scanning lock table for conflicting locks
[6] sequence reqTimeout2: waiting in lock wait-queues
[6] sequence reqTimeout2: lock wait-queue event: wait for txn 00000003 running request @ key ‹"k2"› (queuedLockingRequests: 2, queuedReaders: 0)
[6] sequence reqTimeout2: pushing after 0s for: deadlock/liveness detection = true, timeout enforcement = true, priority enforcement = false, wait policy error = false
[6] sequence reqTimeout2: pushing txn 00000003 to abort
[6] sequence reqTimeout2: pushee not abandoned
[6] sequence reqTimeout2: conflicted with ‹00000003-0000-0000-0000-000000000000› on ‹"k2"› for 0.000s
[6] sequence reqTimeout2: sequencing complete, returned error: conflicting locks on ‹"k2"› [reason=lock_timeout]

# -------------------------------------------------------------
# Read-only request with lock timeout discovers lock. The
# request raises an error.
# -------------------------------------------------------------

new-request name=reqTimeout3 txn=txnNoWait ts=12,0 lock-timeout
  get key=k4
----

sequence req=reqTimeout3
----
[7] sequence reqTimeout3: sequencing request
[7] sequence reqTimeout3: acquiring latches
[7] sequence reqTimeout3: scanning lock table for conflicting locks
[7] sequence reqTimeout3: sequencing complete, returned guard

handle-lock-conflict-error req=reqTimeout3 lease-seq=1
  lock txn=txn2 key=k4
----
[8] handle lock conflict error reqTimeout3: handled conflicting locks on ‹"k4"›, released latches

sequence req=reqTimeout3
----
[9] sequence reqTimeout3: re-sequencing request
[9] sequence reqTimeout3: acquiring latches
[9] sequence reqTimeout3: scanning lock table for conflicting locks
[9] sequence reqTimeout3: waiting in lock wait-queues
[9] sequence reqTimeout3: lock wait-queue event: wait for txn 00000002 holding lock @ key ‹"k4"› (queuedLockingRequests: 0, queuedReaders: 1)
[9] sequence reqTimeout3: pushing after 0s for: deadlock/liveness detection = true, timeout enforcement = true, priority enforcement = false, wait policy error = false
[9] sequence reqTimeout3: pushing timestamp of txn 00000002 above 12.000000000,1
[9] sequence reqTimeout3: pushee not abandoned
[9] sequence reqTimeout3: conflicted with ‹00000002-0000-0000-0000-000000000000› on ‹"k4"› for 0.000s
[9] sequence reqTimeout3: sequencing complete, returned error: conflicting locks on ‹"k4"› [reason=lock_timeout]

debug-lock-table
----
num=3
 lock: "k2"
   queued locking requests:
    active: false req: 3, strength: Intent, txn: 00000003-0000-0000-0000-000000000000
 lock: "k3"
  holder: txn: 00000002-0000-0000-0000-000000000000 epoch: 0, iso: Serializable, ts: 11.000000000,0, info: unrepl [(str: Exclusive seq: 0)]
   queued locking requests:
    active: true req: 3, strength: Intent, txn: 00000003-0000-0000-0000-000000000000
 lock: "k4"
  holder: txn: 00000002-0000-0000-0000-000000000000 epoch: 0, iso: Serializable, ts: 11.000000000,1, info: repl [Intent]

# -------------------------------------------------------------
# Read-only request with lock timeout discovers abandoned
# lock. The request resolves the abandoned lock and proceeds.
# -------------------------------------------------------------

on-txn-updated txn=txn2 status=aborted
----
[-] update txn: aborting txn2
[3] sequence req3: resolving intent ‹"k3"› for txn 00000002 with ABORTED status
[3] sequence req3: lock wait-queue event: done waiting
[3] sequence req3: conflicted with ‹00000002-0000-0000-0000-000000000000› on ‹"k3"› for 0.000s
[3] sequence req3: acquiring latches
[3] sequence req3: scanning lock table for conflicting locks
[3] sequence req3: sequencing complete, returned guard

new-request name=reqTimeout4 txn=txnNoWait ts=12,0 lock-timeout
  get key=k5
----

sequence req=reqTimeout4
----
[10] sequence reqTimeout4: sequencing request
[10] sequence reqTimeout4: acquiring latches
[10] sequence reqTimeout4: scanning lock table for conflicting locks
[10] sequence reqTimeout4: sequencing complete, returned guard

handle-lock-conflict-error req=reqTimeout4 lease-seq=1
  lock txn=txn2 key=k5
----
[11] handle lock conflict error reqTimeout4: handled conflicting locks on ‹"k5"›, released latches

sequence req=reqTimeout4
----
[12] sequence reqTimeout4: re-sequencing request
[12] sequence reqTimeout4: acquiring latches
[12] sequence reqTimeout4: scanning lock table for conflicting locks
[12] sequence reqTimeout4: waiting in lock wait-queues
[12] sequence reqTimeout4: lock wait-queue event: done waiting
[12] sequence reqTimeout4: resolving a batch of 1 intent(s)
[12] sequence reqTimeout4: resolving intent ‹"k5"› for txn 00000002 with ABORTED status
[12] sequence reqTimeout4: acquiring latches
[12] sequence reqTimeout4: scanning lock table for conflicting locks
[12] sequence reqTimeout4: sequencing complete, returned guard

finish req=reqTimeout4
----
[-] finish reqTimeout4: finishing request

finish req=req3
----
[-] finish req3: finishing request

debug-lock-table
----
num=1
 lock: "k4"
  holder: txn: 00000002-0000-0000-0000-000000000000 epoch: 0, iso: Serializable, ts: 11.000000000,1, info: repl [Intent] [holder finalized: aborted]

reset
----
