SitePoint Sponsor

User Tag List

Results 1 to 7 of 7
  1. #1
    SitePoint Enthusiast
    Join Date
    May 2005
    Posts
    37
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    DataMapper Pattern and Transactions

    So I have been doing a bit of reading about the Data Mapper pattern and I mostly understand how it works. But there is one area I don't quite understand and that is how to make a transaction work with multiple mappers. For example I have two classes (Object1 and Object2) and their corresponding data mappers (Object1Mapper and Object2Mapper) and they are mapped two two database tables. When I want to perform a particular action I need to update both of those objects but I need to do that in a transaction to make sure both of those SQL statements succeed. I am not sure how to go about doing that. I should mention that this isn't for any particular project. I am just trying to understand this pattern a little better and broaden my knowledge. Does anyone know how to do this? Thanks.

  2. #2
    Spirit Coder allspiritseve's Avatar
    Join Date
    Dec 2002
    Location
    Ann Arbor, MI (USA)
    Posts
    648
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Do you make two separate calls to the mappers, or does one mapper call another when you save the first? For example, say I have a Post object with a User object as its author. I could call $postMapper->save ($post), and PostMapper could extract User and pass it to UserMapper... or, I could call $postMapper->save ($post) and $userMapper->save ($post->getAuthor()).

    For the first method, you could handle transactions inside each mapper. Each mapper checks if a transaction is already started, and if not, starts one itself. If a transaction is already started, then it just goes about its business. The other option is probably a UnitOfWork... you can google that one.

  3. #3
    SitePoint Enthusiast
    Join Date
    May 2005
    Posts
    37
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I understand what your saying but what if the two objects are not really related to each other? What I would like to do with mappers is similar to this pseudo code:

    PHP Code:
    $dbConn->beginTransaction();
    $post->save();
    $someOtherObject->save();
    $dbConn->commit(); 
    The SQL statements from the mappers wouldn't execute until the commit. If the object contains other objects, those would also be included in the transaction. Is this sort of thing even possible with data mappers? Thanks.

  4. #4
    Spirit Coder allspiritseve's Avatar
    Join Date
    Dec 2002
    Location
    Ann Arbor, MI (USA)
    Posts
    648
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    In that case you're definitely looking for UnitOfWork. Though I do wonder why you need a transaction to persist two objects that "are not really related to each other".

  5. #5
    SitePoint Enthusiast
    Join Date
    May 2005
    Posts
    37
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thank you for your replies. I think my wording of "not really related to each other" is not very good. What I mean is I want all or nothing when I persist more than one object to the database. That is why I want to wrap it in a transaction. I will read about the Unit Of Work in more detail. Thanks for your help. :-)

  6. #6
    SitePoint Zealot
    Join Date
    Jun 2004
    Location
    Netherlands
    Posts
    172
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    I have had the same problem. With nested transactions not being possible. Say
    PHP Code:
    class ObjectA {
    function 
    save(){
      
    $dbh->start(); // start transaction
      
    try {
      
    $b = new ObjectB();
      
    $b->save();
      
    // etc
      
    $dbh->commit(); // commit
      
    } catch() {
      
    $dbh->rollback();
      }
    }
    }
    class 
    ObjectB {
      function 
    save(){
        
    $dbh->start();// start transaction
        
    try {
          
    // save to db  
         
    $dbh->commit(); // commit
        
    } catch () {
          
    $dbh->rollback();// rollback
        
    }
      }
    }
    $a = new ObjectA();
    $a->save(); 
    Normally this is not possible because nested transactions are not allowed. The trick is here to let your Db handler sort out the transactions. I found a good solution in the code of EzComponents
    http://ezcomponents.org/docs/tutorials/Database
    you should download the framework and look at the
    abstract class ezcDbHandler extends PDO

  7. #7
    SitePoint Enthusiast
    Join Date
    May 2005
    Posts
    37
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thank you for the reply. The EzComponents information proved to be informative. Thanks for your help. :-)


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •