nested transactions and communicating to other processes

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

nested transactions and communicating to other processes

Dami Laurent (PJ)
Hi there,

I encountered a delicate situation involving nested transactions.
Consider a subroutine more or less like this :

  sub insert_and_publish {
    my @keys = $schema->txn_do(sub {some_complex_inserts()});
    publish_to_outer_world(@keys);
  }

This creates a bunch of records within a transaction. If the transaction succeeds, changes are commited to the database, and then we can publish the record keys to other processes. With one single transaction, everything is well. However, if this is called from another transaction, we get into trouble :

  $schema->txn_do(sub {
    insert_and_publish();
    do_some_more_stuff();
   });
   # only now did the real commit take place

The problem here is that because of nested transactions, the commit only takes place at the outermost level; so the sequence of operations in insert_and_publish() no longer works : other processes get notified about keys that have not been committed yet (because do_some_more_stuf() might take some time), or possibly will never be committed (because do_some_more_stuf() might fail).

The question is : how to rewrite insert_and_publish() so that it would work equally well in a single transaction, or in a nested transaction ? It seems that what is needed is a callback mechanism, to record things that should be done just after the transaction, and would be called automatically after commit time. Any suggestions ?

Thanks in advance, Laurent Dami

_______________________________________________
List: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class
IRC: irc.perl.org#dbix-class
SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
Searchable Archive: http://www.grokbase.com/group/dbix-class@...
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: nested transactions and communicating to other processes

Mitchell Elutovich
Why not have insert_and_publish return a function that it would like the caller to call after the commit.  The body of the function would be your publish_to_outer_world(@keys);

On Thu, Oct 23, 2014 at 4:32 AM, Dami Laurent (PJ) <[hidden email]> wrote:
Hi there,

I encountered a delicate situation involving nested transactions.
Consider a subroutine more or less like this :

  sub insert_and_publish {
    my @keys = $schema->txn_do(sub {some_complex_inserts()});
    publish_to_outer_world(@keys);
  }

This creates a bunch of records within a transaction. If the transaction succeeds, changes are commited to the database, and then we can publish the record keys to other processes. With one single transaction, everything is well. However, if this is called from another transaction, we get into trouble :

  $schema->txn_do(sub {
    insert_and_publish();
    do_some_more_stuff();
   });
   # only now did the real commit take place

The problem here is that because of nested transactions, the commit only takes place at the outermost level; so the sequence of operations in insert_and_publish() no longer works : other processes get notified about keys that have not been committed yet (because do_some_more_stuf() might take some time), or possibly will never be committed (because do_some_more_stuf() might fail).

The question is : how to rewrite insert_and_publish() so that it would work equally well in a single transaction, or in a nested transaction ? It seems that what is needed is a callback mechanism, to record things that should be done just after the transaction, and would be called automatically after commit time. Any suggestions ?

Thanks in advance, Laurent Dami

_______________________________________________
List: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class
IRC: irc.perl.org#dbix-class
SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
Searchable Archive: http://www.grokbase.com/group/dbix-class@...


_______________________________________________
List: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class
IRC: irc.perl.org#dbix-class
SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
Searchable Archive: http://www.grokbase.com/group/dbix-class@...
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: nested transactions and communicating to other processes

Aran Deltac-2
In reply to this post by Dami Laurent (PJ)
AFAIK there is no native way to make this situation easier, if thats what you are hoping for.  You could make a stack on the engine object where you could pop on things todo when a transaction is committed, and then modify the commit sub to unpop and run the stack after commit.  Not sure how good of a design that is, and makes a lot of action-at-a-distance, making things a bit harder to debug and possibly introducing weird edge case issues.

Aran

On Thu, Oct 23, 2014 at 1:32 AM, Dami Laurent (PJ) <[hidden email]> wrote:
Hi there,

I encountered a delicate situation involving nested transactions.
Consider a subroutine more or less like this :

  sub insert_and_publish {
    my @keys = $schema->txn_do(sub {some_complex_inserts()});
    publish_to_outer_world(@keys);
  }

This creates a bunch of records within a transaction. If the transaction succeeds, changes are commited to the database, and then we can publish the record keys to other processes. With one single transaction, everything is well. However, if this is called from another transaction, we get into trouble :

  $schema->txn_do(sub {
    insert_and_publish();
    do_some_more_stuff();
   });
   # only now did the real commit take place

The problem here is that because of nested transactions, the commit only takes place at the outermost level; so the sequence of operations in insert_and_publish() no longer works : other processes get notified about keys that have not been committed yet (because do_some_more_stuf() might take some time), or possibly will never be committed (because do_some_more_stuf() might fail).

The question is : how to rewrite insert_and_publish() so that it would work equally well in a single transaction, or in a nested transaction ? It seems that what is needed is a callback mechanism, to record things that should be done just after the transaction, and would be called automatically after commit time. Any suggestions ?

Thanks in advance, Laurent Dami

_______________________________________________
List: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class
IRC: irc.perl.org#dbix-class
SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
Searchable Archive: http://www.grokbase.com/group/dbix-class@...


_______________________________________________
List: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class
IRC: irc.perl.org#dbix-class
SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
Searchable Archive: http://www.grokbase.com/group/dbix-class@...
Loading...