Using transactions with Ruby DataMapper

With DataMapper, it can be quite a challenge to perform tasks that seem so simple at first. DataMapper is an object-relational mapper (ORM) written in Ruby, with a lot of great features and innovative approaches to common ORM-tasks. But it lacks documentation for some of the less-used features and even the more popular search engines don’t have the answer to all questions.

Note: the following examples have been tested with DataMapper version 0.10.2.

One of the questions I had was how to perform multiple queries within a single (database) transaction, so that I can ’stage’ a number of database queries and commit (or rollback) them all in one go. Fortunately, after some investigation of the DataMapper source code, it turns out to be an extremely simple task:

User.transaction do
  User.first.update(:name => "John Smith")
  Address.first.update(:street => "") # Invalid: street must not be blank
end

With this code neither the address nor the user will be updated in the database if one of the updates fails. The syntax is actually the same as for the ActiveRecord ORM. However, triggering a rollback is done differently, as can be seen in the following example.

User.transaction do |t|
  User.first.update(:name => "John Smith")
  Address.first.update(:street => "Oak St. 400")
  t.rollback # Transaction will be rolled back even when updates are OK.
end

That’s it for now. I’m sure there are some additional features that I haven’t mentioned here, but this is all I had to know at this point.

Share and Enjoy:
  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • DZone
  • email
  • Hyves
  • Reddit
  • StumbleUpon
  • Twitter
This entry was posted in ruby. Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

One Comment

  1. Posted January 22, 2010 at 09:05 | Permalink

    To mimic AR’s behaviour, you could do the following

    User.transaction do |t|
      begin
        User.first.update(:name => "John Smith")
        Address.first.update(:street => "Oak St. 400")
      rescue
        t.rollback
      end
    end

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">