Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7762269
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 1, 20262026-06-01T14:21:22+00:00 2026-06-01T14:21:22+00:00

Can one transaction update two different TVar s in an atomic way? i.e. can

  • 0

Can one transaction update two different TVars in an atomic way? i.e. can I compose data structures out of lots of TVars to reduce contention? If so, could you provide an example?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-01T14:21:23+00:00Added an answer on June 1, 2026 at 2:21 pm

    Can one transaction update two different TVars in an atomic way?

    Yes, you can update multiple TVars atomically in one transaction. That’s sort of the whole point of STM. It wouldn’t be very useful if you couldn’t.

    Can I compose data structures out of lots of TVars to reduce contention? If so, could you provide an example?

    Here is a (somewhat silly) example of storing TVars in a data structure. It simulates a bunch of random concurrent transactions between accounts in a bank, where each account is just a TVar Integer. The account TVars are kept in a map from account IDs, which is itself kept in a TVar so that new accounts can be created on the fly.

    import Control.Concurrent
    import Control.Concurrent.MVar
    import Control.Concurrent.STM
    import Control.Monad
    import System.Random
    
    import qualified Data.Map as Map
    
    type AccountId = Int
    type Account = TVar Dollars
    type Dollars = Integer
    type Bank = TVar (Map.Map AccountId Account)
    
    numberOfAccounts = 20
    threads = 100
    transactionsPerThread = 100
    maxAmount = 1000
    
    -- Get account by ID, create new empty account if it didn't exist
    getAccount :: Bank -> AccountId -> STM Account
    getAccount bank accountId = do
      accounts <- readTVar bank
      case Map.lookup accountId accounts of
        Just account -> return account
        Nothing -> do
          account <- newTVar 0
          writeTVar bank $ Map.insert accountId account accounts
          return account
    
    -- Transfer amount between two accounts (accounts can go negative)
    transfer :: Dollars -> Account -> Account -> STM ()
    transfer amount from to = when (from /= to) $ do
      balanceFrom <- readTVar from
      balanceTo <- readTVar to
      writeTVar from $! balanceFrom - amount
      writeTVar to $! balanceTo + amount
    
    randomTransaction :: Bank -> IO ()
    randomTransaction bank = do
      -- Make a random transaction
      fromId <- randomRIO (1, numberOfAccounts)
      toId   <- randomRIO (1, numberOfAccounts)
      amount <- randomRIO (1, maxAmount)
    
      -- Perform it atomically
      atomically $ do
        from <- getAccount bank fromId
        to   <- getAccount bank toId
        transfer amount from to
    
    main = do
      bank <- newTVarIO Map.empty
    
      -- Start some worker threads to each do a number of random transactions
      workers <- replicateM threads $ do
        done <- newEmptyMVar
        forkIO $ do
          replicateM_ transactionsPerThread $ randomTransaction bank
          putMVar done ()
        return done
    
      -- Wait for worker threads to finish
      mapM_ takeMVar workers
    
      -- Print list of accounts and total bank balance (which should be zero)
      summary <- atomically $ do
        accounts <- readTVar bank
        forM (Map.assocs accounts) $ \(accountId, account) -> do
          balance <- readTVar account
          return (accountId, balance)
    
      mapM_ print summary
      putStrLn "----------------"
      putStrLn $ "TOTAL BALANCE: " ++ show (sum $ map snd summary)
    

    This should print a total balance of zero at the end if there were no race conditions during the transfers.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm using subversion so that I can have two checkouts, one for testing to
I am updating the attributes of two models from one form. User.transaction do begin
Can one place an arbitrary program (firefox, openoffice, etc...) in a QX11EmbedContainer? The fllowing
Can one of you smarties point me to some beginner content for converting an
Can one upload files to a domain other than the domain a script originates
Can one call a method from another model in a model in CodeIgniter? I
How can one call a ColdFusion function, passing in attribute values as arguments, inside
How can one best test a controller action which receives a file upload using
How can one replace a part of a line with sed? The line DBSERVERNAME
How can one have more than a Wizard control on the same page without

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.