how to implement Transactions (over different db tables) in a Catalyst project

4 messages Options
Embed this post
Permalink
kakimoto

how to implement Transactions (over different db tables) in a Catalyst project

Reply Threaded More More options
Print post
Permalink
hi, everyone,

 I finally looked at the updated doc for txn_do and transactions have
been implemented correctly in my application.

Nevertheless, I do have a few questions (at the bottom).





sub save_complete_records
{
 ...

 eval
 {
     $c->model('myAppDB')->schema->txn_do( sub
         {
           ...
          $c->forward(
                   '/subscriptions/_save_address',
                   [
                       { 'policy_id' => $policy_id, }
                   ]
          );

          ...
 }
  if ($@)
  {
       $c->log->debug(' Exception manually trapped here : ' . $@ );
       $c->model('myAppDB')->schema->txn_rollback or die "Cannot ROLL
BACK - Address module";
       $c->log->debug(' manually rolled back' );
       $c->error(
           q{ An error has occured with the listing. If this problem } .
           q{persists please contact our helpdesk at
helpdesk@insuranceline.}.
           q{com.nz.}
       );
  }
}


To test, I purposedly entered a very long string for one of the database
attributes to make the transaction fail.

I have the following questions:
1) I looked at the terminal with all the debug messages. I noticed that
the exception was caught and eventhough the roll back was done, I do not
see the print outs from the liens within the "if ($@)" (exception
handling) section above. Why is that?

2) I noticed that whilst the rollback was successful. the sequence do
not get rolled back. IS this desired behaviour of DBIx::Class?

 To illustrate,  before the exception was caught, an entry was made in
my User_Subscriptions database table. The ID was printed out and I took
note of it.

When the operation was complete, I queried my User_Subscriptions
database table (using psql for postgresql for an entry of the noted ID).
No entry of the noted ID was returned.

I went back to the webpage and entered the form with valid attributes
and yes, all necessary objects were created in the database backend and
the sequence
in the User_Subscriptions database table had increased by 1.

Any ideas?


 thank you :)


k. akimoto

_______________________________________________
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@...
Tomas Doran

Re: how to implement Transactions (over different db tables) in a Catalyst project

Reply Threaded More More options
Print post
Permalink
[hidden email] wrote:
> 2) I noticed that whilst the rollback was successful. the sequence do
> not get rolled back. IS this desired behaviour of DBIx::Class?

This is a postgres thing, not a DBIC thing.

And no, sequences don't get rolled back.

Consider, imagining sequence starts at 1:
A: {start trans, INSERT ROW (seq 2)}
B: {start trans, INSERT ROW (seq 3)}
Seq is now 3
B: {commit}
A: {rollback}?

If you roll the sequence back 1 as A rolled back, the sequence is 2, so
when you next insert you have a duplicate seq (as B is committed).

Couldn't work, without keeping track of which previous sequence values
had been rolled back. It'd also not be a sequence if you could ask for
two values and the second was lower than the first :)

Cheers
t0m

_______________________________________________
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@...
Rob Kinyon

Re: how to implement Transactions (over different db tables) in a Catalyst project

Reply Threaded More More options
Print post
Permalink
On Tue, Jul 7, 2009 at 06:34, Tomas Doran<[hidden email]> wrote:

> [hidden email] wrote:
>>
>> 2) I noticed that whilst the rollback was successful. the sequence do
>> not get rolled back. IS this desired behaviour of DBIx::Class?
>
> This is a postgres thing, not a DBIC thing.
>
> And no, sequences don't get rolled back.
>
> Consider, imagining sequence starts at 1:
> A: {start trans, INSERT ROW (seq 2)}
> B: {start trans, INSERT ROW (seq 3)}
> Seq is now 3
> B: {commit}
> A: {rollback}?
>
> If you roll the sequence back 1 as A rolled back, the sequence is 2, so when
> you next insert you have a duplicate seq (as B is committed).
>
> Couldn't work, without keeping track of which previous sequence values had
> been rolled back. It'd also not be a sequence if you could ask for two
> values and the second was lower than the first :)

Furthermore, a sequence is SOLELY to generate AN UNUSED NUMBER so that
you can have a guaranteed value that will work for a primary key. You
should not depend on that value for anything other than uniqueness.
You cannot sort by it to get the rows in insertion order. You cannot
guarantee that there are no gaps. Nothing. If you need anything
predictable, add it yourself.

And this is true for all RDBMS sequences, whether in Postgres, Oracle,
MySQL, Sybase, or MSSQL. It would be best if everyone just treated a
sequence as a UUID generator - a random number that is guaranteed to
be unique and has NO OTHER PROPERTIES.

Rob

_______________________________________________
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@...
Peter Rabbitson-2

Re: how to implement Transactions (over different db tables) in a Catalyst project

Reply Threaded More More options
Print post
Permalink
In reply to this post by kakimoto
On Tue, Jul 07, 2009 at 08:44:13AM +1000, [hidden email] wrote:

> hi, everyone,
>
>  I finally looked at the updated doc for txn_do and transactions have
> been implemented correctly in my application.
>
> Nevertheless, I do have a few questions (at the bottom).
>
>
>
>
>
> sub save_complete_records
> {
>  ...
>
>  eval
>  {
>      $c->model('myAppDB')->schema->txn_do( sub
>          {
>            ...
>           $c->forward(
>                    '/subscriptions/_save_address',
>                    [
>                        { 'policy_id' => $policy_id, }
>                    ]
>           );
>
>           ...
>  }
>   if ($@)
>   {
>        $c->log->debug(' Exception manually trapped here : ' . $@ );
>        $c->model('myAppDB')->schema->txn_rollback or die "Cannot ROLL
> BACK - Address module";
>        $c->log->debug(' manually rolled back' );
>        $c->error(
>            q{ An error has occured with the listing. If this problem } .
>            q{persists please contact our helpdesk at
> helpdesk@insuranceline.}.
>            q{com.nz.}
>        );
>   }
> }
>
>
> To test, I purposedly entered a very long string for one of the database
> attributes to make the transaction fail.
>
> I have the following questions:
> 1) I looked at the terminal with all the debug messages. I noticed that
> the exception was caught and eventhough the roll back was done, I do not
> see the print outs from the liens within the "if ($@)" (exception
> handling) section above. Why is that?

Because you did not end your eval with a ';', and you are not running
with strict/warnings? :)


_______________________________________________
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@...