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.