On Wed, 06 Sep 2000 11:23:37 -0400, Dan Sugalski wrote:

>>Here's some high-level emulation of what it should do.
>>
>>         eval {
>>                 my($_a, $_b, $c) = ($a, $b, $c);
>>                 ...
>>                 ($a, $b, $c) = ($_a, $_b, $_c);
>>         }
>
>Nope. That doesn't get you consistency. What you need is to make a local 
>alias of $a and friends and use that.

My example should have been clearer. I actually intended that $_a would
be a variable of the same name as $a. It's a bit hard to write currently
valid code that way. Second attempt:

        eval {
            ($a, $b, $c) = do {
                local($a, $b, $c) = ($a, $b, $c); #or my(...)
                ...     # code which may fail
                ($a, $b, $c);
            };
        };

So the final assignment of the local values to the outer scoped
variables will happen, and in one go, only if the whole block has been
executed succesfully.
        
>You also need to lock down those 
>variables so other threads will block if they write to them, and make 
>copies if they need to only read them.

That is partly why I used lexical variables. Other threads will NOT see
the new values, but the old values, as long as the final back assignment
hasn't happened.

I would simply block ALL other threads while the final group assignment
is going on. This should finish typically in a few milliseconds.

>It also means that if we're including *any* sort of external pieces (even 
>files) in the transaction scheme we need to have some mechanism to roll 
>back changes. If a transaction fails after truncating a 12G file and 
>writing out 3G of data, what do we do?

That does not belong in the kernel of a language. All that you may
expect, is transactions on simple variables; plus maybe some hooks to
attach external transaction code (transactions on files etc) to it. A
simple "create a new file, and rename to the old filename when done"
will usually do.

-- 
        Bart.

Reply via email to