[Ur] missing transactions (was Code review request)

Sergey Mironov grrwlf at gmail.com
Thu Apr 10 16:15:46 EDT 2014


The following patch fixes the issue for me

https://raw.githubusercontent.com/grwlf/urweb-callback/d11bea0f03c03ceddbb5cf2183119ba8e798c49f/4_of_4_Tweak_transactional_callabcks.patch

Latest urweb-callback survives the stress test with this patch applied.

Regards,
Sergey


2014-04-10 17:00 GMT+04:00 Sergey Mironov <grrwlf at gmail.com>:
> Hi again! Looks like there are no people around who are brave enough
> to look into my code :)) But that's alright: after deep debugging I've
> fixed the segfaults (my mistake). And it is not the end of story:
>
> I've run a stress testing and it shows that some database transactions
> just disappear . Investigation shows an interesting point in uw_commit
> (see the code below). The code says that it is possible to return from
> the [uw_commit] function after calling all the
> transactionals[i].commit handlers (return 1 after db_commit). I think
> it is clearly a bug, since the user applications (like urweb-callback)
> think that everything is OK at this point. I've done some testing and
> it shows that this returns really happen from time to time under high
> load.
>
> So there are two questions:
>
>  1. What should application do if database commit fails? Probably, the
> answer is - report the error to client.
>  2. How to notify the ctx->transactionals about successful db_commit?
> Looks like we can't do that at the moment.  Here I suggest rewriting
> the code: call NULL-rolllbacked commits _after_ the db_commit point
> (and forbid raising errors for such handlers). This way we can really
> handle the non-transactional actions.
>
> Please, comment.
>
> Regards,
> Sergey
>
>
> --
>
> urweb.c   line 3291
>
>   for (i = ctx->used_transactionals-1; i >= 0; --i)
>     if (ctx->transactionals[i].rollback != NULL)
>       if (ctx->transactionals[i].commit) {
>         ctx->transactionals[i].commit(ctx->transactionals[i].data);
>         if (uw_has_error(ctx)) {
>           uw_rollback(ctx, 0);
>           return 0;
>         }
>       }
>
>   for (i = ctx->used_transactionals-1; i >= 0; --i)
>     if (ctx->transactionals[i].rollback == NULL)
>       if (ctx->transactionals[i].commit) {
>         ctx->transactionals[i].commit(ctx->transactionals[i].data);
>         if (uw_has_error(ctx)) {
>           uw_rollback(ctx, 0);
>           return 0;
>         }
>       }
>
>   if (ctx->transaction_started) {
>     int code = ctx->app->db_commit(ctx);
>
>     if (code) {
>       if (code == -1)
>         return 1;  // <--- HERE !
>
>       for (i = ctx->used_transactionals-1; i >= 0; --i)
>         if (ctx->transactionals[i].free)
>           ctx->transactionals[i].free(ctx->transactionals[i].data, 0);
>
>       uw_set_error_message(ctx, "Error running SQL COMMIT");
>       return 0;
>     }
>   }
>
>
>
> 2014-04-07 0:50 GMT+04:00 Sergey Mironov <grrwlf at gmail.com>:
>> Probably I should mention this thing: the notifiers::init() from
>> CallbackFFI.cpp:377 is called by the `task initialize' in the
>> Callback.ur
>>
>> https://github.com/grwlf/urweb-callback/blob/devel/Callback.ur#L18
>>
>>
>> Sergey



More information about the Ur mailing list