Skip to content

Commit

Permalink
feat: verify the state of transaction
Browse files Browse the repository at this point in the history
Signed-off-by: Kengo TODA <skypencil@gmail.com>
  • Loading branch information
KengoTODA committed Apr 10, 2024
1 parent cbbbd22 commit 6a7933c
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 1 deletion.
Expand Up @@ -30,6 +30,7 @@ class OnMemoryTable(private val name: String) : Table {
id: RowId,
): Row =
lock.withLock {
requireActiveTransaction(tx)
checkNotNull(map[id]) {
"$this does not contain $id"
}
Expand All @@ -40,6 +41,7 @@ class OnMemoryTable(private val name: String) : Table {

override suspend fun tableScan(tx: Transaction): Sequence<Row> =
lock.withLock {
requireActiveTransaction(tx)
map.entries.mapNotNull {
snapshotAt(tx, it.key)
}.asSequence()
Expand All @@ -50,6 +52,7 @@ class OnMemoryTable(private val name: String) : Table {
row: Row,
) {
lock.withLock {
requireActiveTransaction(tx)
check(map[row.id] == null) {
"$this already has $row"
}
Expand All @@ -60,13 +63,18 @@ class OnMemoryTable(private val name: String) : Table {
override suspend fun delete(
tx: Transaction,
id: RowId,
): Boolean = lock.withLock { map.remove(id) != null }
): Boolean =
lock.withLock {
requireActiveTransaction(tx)
map.remove(id) != null
}

override suspend fun update(
tx: Transaction,
row: Row,
) {
lock.withLock {
requireActiveTransaction(tx)
val history =
checkNotNull(map[row.id]) {
"$this does not contain ${row.id}"
Expand All @@ -76,4 +84,10 @@ class OnMemoryTable(private val name: String) : Table {
}

override fun toString() = "Table(name=$name)"

private fun requireActiveTransaction(tx: Transaction) {
require(tx.isActive()) {
"Given $tx is not active"
}
}
}
Expand Up @@ -35,4 +35,6 @@ class TransactionManager {
fun rollback(tx: Transaction) {
activeTransactions.remove(tx.id)
}

fun checkActive(tx: Transaction): Boolean = activeTransactions.contains(tx.id)
}
Expand Up @@ -10,5 +10,7 @@ data class Transaction(val id: TransactionId, private val transactionManager: Tr
return id == another.id || id < another.id && transactionManager.isCommitted(id, another.id)
}

fun isActive(): Boolean = transactionManager.checkActive(this)

override fun toString(): String = "Transaction(id=$id)"
}
Expand Up @@ -61,4 +61,18 @@ class OnMemoryTableSpec : DescribeSpec({
val exception = shouldThrow<IllegalStateException> { table.find(tx2, row1.id) }
exception.message shouldBe "$table does not contain ${row1.id}"
}
it("throws exception when committed transaction is used") {
val txManager = TransactionManager()
val table = OnMemoryTable("example")
val tx1 = txManager.create()
val row1 = Row(RowId.create())
table.insert(tx1, row1)
txManager.commit(tx1)

val exception =
shouldThrow<IllegalArgumentException> {
table.find(tx1, row1.id)
}
exception.message shouldBe "Given $tx1 is not active"
}
})

0 comments on commit 6a7933c

Please sign in to comment.