moshimoshi
moshimoshi

Reputation: 251

Write an atomic operation

I would like to execute some methods atomicity with Ruby, according to http://en.wikipedia.org/wiki/Atomicity_(database_systems)

For instance, if I have:

a = 30
b = 75

I would like to be able to do something like:

atomic_operation do
  a += 10
  b -= 39
end

Is there a native module in Ruby 1.9 that allow such process? If possible, I would like to do so without using a plugin. Many thanks!

Upvotes: 8

Views: 5660

Answers (5)

zimbatm
zimbatm

Reputation: 812

The Mutex class is available in the 1.9 runtime (and require('thread') in 1.8) and allows you to lock operations in a context.

# Typically defined in the object initializer
@lock = Mutex.new

# Then in your code
@lock.synchronize do
  a += 10
  b -= 39
end

This will guarantee you that the block given to Mutex#synchronize is run sequentially.

Official doc is here: http://rubydoc.info/stdlib/core/1.9.2/Mutex

Upvotes: 7

abhijit
abhijit

Reputation: 6723

Have you had a look at the 'Transaction Simple' gem?

I think that would suit your purpose

http://rubyforge.org/projects/trans-simple

Upvotes: 0

Sai Venkat
Sai Venkat

Reputation: 1248

What you need my friend is a Software transactional memory. Try out the STM implementation I have been playing with in JRuby (You need to checkout the code in repo as I haven't packaged it for the release).

Also check out Ruby atomic I am working on http://github.com/saivenkat/ruby-atomic. Gives you CAS type of operations on MRI. This is a bit lower level but will help you with the same problem. I haven't written Transactional Memory for MRI one but with the CAS infrastructure it won't be long :)

P.S Stackoverflow doesn't let me post more than one link as I didn't use its system a lot. So checkout the multiverse site in codehaus for STM in JRuby

--Sai Venkat

Upvotes: 2

Chubas
Chubas

Reputation: 18053

As you point to an article about databases, I'm guessing you are asking in this context.

If you are using Rails, you use the transaction methods of ActiveRecord.

Account.transaction do
  @alice.withdraw!(100)
  @bob.deposit!(100)
end

If using outside of Rails, you have to work with what the database driver library provides. Check the implementation of transaction on Rails to get an idea of how it can be done.

Upvotes: 6

Mike Tunnicliffe
Mike Tunnicliffe

Reputation: 10772

It really depends on the scope you are interested in as to the right tools for the job. If you are looking to perform an atomic operation on a database, then the database driver will probably (if it's any good/the database supports it) offer a way to use a database transaction to make updates atomic.

If you are talking about a multi-threaded Ruby application attempting to makes updates to shared resources atomic and thread-safe, then Ruby provides the Mutex and ConditionVariable classes to help you out in that regard. (More info: http://ruby-doc.org/docs/ProgrammingRuby/html/tut_threads.html)

Upvotes: 8

Related Questions