withTransaction

suspend fun KilnDriver.withTransaction(context: CoroutineContext = Dispatchers.Default, block: suspend () -> Unit)

Executes block inside a single SQLite transaction.

All INSERT / UPDATE / DELETE operations performed by Kiln repositories inside block have their KilnDriver.notifyListeners calls deferred. After the outermost COMMIT, each dirty table is notified exactly once — reactive flows therefore receive one emission per transaction rather than one per operation. This holds whoever opened the outermost transaction: a block run inside a transaction opened by other code on the same driver joins it, and notifies only once that transaction commits.

Blocks nest: a withTransaction inside another joins it, and only the outermost one commits.

On any exception the transaction is rolled back and the exception re-thrown. No notifications are sent for a rolled-back transaction.

The transaction holds one thread of context until it completes — SQLite transactions belong to the thread that opened them, so a suspended block resumes on that thread, and repository calls inside the block run there too. Pass Dispatchers.IO for a transaction that waits on I/O, so it doesn't hold one of Dispatchers.Default's few threads.