From 495b54921954c32728b55a7de4537de7867ad021 Mon Sep 17 00:00:00 2001 From: Ramakrishnan Muthukrishnan <ram@leastauthority.com> Date: Thu, 24 Oct 2019 17:04:05 +0530 Subject: [PATCH] do the read/write operations from the db should be in a transaction `redeemVoucher' reads stuff from the db, makes decisions and then writes to the db. However if there is another client doing a simultaneous `redeemVoucher' for the same `voucher', then both of them would redeem the voucher, which is incorrect. The operations should have exclusive access to the db and this is achieved with `withExclusiveTransaction`. --- src/PaymentServer/Persistence.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PaymentServer/Persistence.hs b/src/PaymentServer/Persistence.hs index 963550f..bdc3eb0 100644 --- a/src/PaymentServer/Persistence.hs +++ b/src/PaymentServer/Persistence.hs @@ -101,7 +101,7 @@ instance VoucherDatabase VoucherDatabaseState where let insertFn = (modifyIORef redeemed .) . Map.insert redeemVoucherHelper (unpaid, existingFingerprint) voucher fingerprint insertFn - redeemVoucher SQLiteDB { conn = conn } voucher fingerprint = do + redeemVoucher SQLiteDB { conn = conn } voucher fingerprint = Sqlite.withExclusiveTransaction conn $ do unpaid <- isVoucherUnpaid conn voucher existingFingerprint <- getVoucherFingerprint conn voucher let insertFn = insertVoucherAndFingerprint conn -- GitLab