Re: RFC 130 (v4) Transaction-enabled variables for Perl6
/--- On Tue, Sep 05, 2000 at 10:57:30PM -0400, Chaim Frenkel wrote: | > "JH" == Jarkko Hietaniemi <[EMAIL PROTECTED]> writes: | | >> Now, "all" that needs to be taken care of, is make sure that | >> the final | >> assignment from the localized and changed variables to their | >> outer-scoped counterparts happens in *one step*, i.e. no task | >> switching | >> while this is going on. | | JH> Well, that can't be done. (I assume that by 'task switching' | you mean | JH> here 'thread switching') Or, if it can, it *shouldn't* be | done. | JH> Threads run on their own until they yield, they decide to | synchronize | JH> and/or join, or they exit. Note the "they decide". \--- It is a very interesting problem, and this maybe out of my profession, but I think we need to try to solve this, because it will worth later! My suggestions: 1, If we use locks for transactions, then we need a deadlock detection, which is (in the simplest case): timeout. It can be implemented very easily. 2, Releasing the lock after the end of transaction has no problem (I think), because we can hold the lock on the variables until we finishes all the COMMITS and TIE_COMMITS, and then we can start releasing the locks. If a task-switching occures in this cycle, then nothing interresting happens: half of the variables are usable by others, half ot that is not. Anyone can try to use that, and may succeed. Next thread-switch to our thread will continue to release the locks until all the locks are released. I still think that we can implement this in a quite simple way IF we assume we already designed our perl interpreter to thread-safe. If you still have objections, share with us! dLux --
Re: RFC 127 (v1) Sane resolution to large function returns
> "GL" == Glenn Linderman <[EMAIL PROTECTED]> writes: GL> Chaim Frenkel wrote: >> ($foo, $baz, @bar) = (1,(2,3),4) # $foo = 1 $baz=2, @bar=(3,4) >> >> Actually, looking at it like that makes it an ugly situation. The 'new' >> expectation would be to have it become >> # $foo=1 $baz=2 @bar=(4) GL> Actually? How about it becoming GL> $foo = 1, $baz =3, @bar = (4) GL> Remember what the following does: GL> $baz = ( 2, 3 ); I certainly do. But what is the context on the RHS. list, so the other interpretation could hold just a well $baz = () = (2,3) # $baz = 2 -- Chaim FrenkelNonlinear Knowledge, Inc. [EMAIL PROTECTED] +1-718-236-0183
Re: RFC 178 (v2) Lightweight Threads
> DS> I'd definitely rather perl not do any sort of explicit user-level locking. > DS> That's not our job, and there be dragons. > Please explain how this is possible? Just say no...to locks. > Does this mean that without user specifying a lock, perl will allow > a chaotic update pattern to be visible to the user? I don't know what `chaotic' means. The user can certainly create race conditions. > thread Athread B > push(@foo, $bar); ++$bar; #!/my/path/to/perl use Thread; $bar = 0; async { ++$bar } push @foo, $bar; print $foo[0]; Output: 0 or 1 If the user cares whether the output is 0 or 1, they need to program a lock. Something like #!/my/path/to/perl use Thread; { $bar = 0; lock $bar; async { lock $bar; ++$bar } push @foo, $bar; } print $foo[0]; Output: 0. > or > $foo{$bar} = $baz; delete $foo{$bar++}; #!/my/path/to/perl use Thread; %foo = ( 1 => 'a', 2 => 'b' ); $bar = 1; $baz = 'x'; async { delete $foo{$bar++} } $foo{$bar} = $baz; print $foo{$bar}; Exeuction trace Thread1 Thread2 Case 1 $foo{$bar} = $baz; print $foo{$bar}; delete $foo{$bar} $bar++ Output: 'x' Case 2 $foo{$bar} = $baz; delete $foo{$bar} print $foo{$bar}; $bar++ Output '' Case 3 $foo{$bar} = $baz; delete $foo{$bar} $bar++ print $foo{$bar}; Output 'b' Case 4 delete $foo{$bar} $foo{$bar} = $baz; $bar++ print $foo{$bar}; Output 'b' Case 5 delete $foo{$bar} $bar++ $foo{$bar} = $baz; print $foo{$bar}; Output 'x' Hey! This is fun :) > Will there be some sort of coherence here? What does coherence mean? - SWM
Re: YAVTBL: yet another vtbl scheme
> "BS" == Benjamin Stuhl <[EMAIL PROTECTED]> writes: BS> variables BS> "know" how to perform ops upon themselves. An operation is BS> separate from the data it operates on. Therefore, I propose BS> the following vtbl scheme, with two goals: The point is to avoid the switches. There is no need for a type flag, in the normal high speed operation. The operator that's in the right place at the right time gets called. BS> opcodes. Every op checks to see if it is overloaded, and if BS> it is, calls that. Some ops don't need to (ie, vec() can BS> just do a set_string and add an OVERLOAD for the bitwise BS> ops). But that's against the point. Nothing has to check. The only operation that is called is the correct one. -- Chaim FrenkelNonlinear Knowledge, Inc. [EMAIL PROTECTED] +1-718-236-0183
Re: RFC 130 (v4) Transaction-enabled variables for Perl6
> "JH" == Jarkko Hietaniemi <[EMAIL PROTECTED]> writes: >> Now, "all" that needs to be taken care of, is make sure that the final >> assignment from the localized and changed variables to their >> outer-scoped counterparts happens in *one step*, i.e. no task switching >> while this is going on. JH> Well, that can't be done. (I assume that by 'task switching' you mean JH> here 'thread switching') Or, if it can, it *shouldn't* be done. JH> Threads run on their own until they yield, they decide to synchronize JH> and/or join, or they exit. Note the "they decide". I think what he _really_ should have said, is a lock is taken on all relevant structures and an update is performed. This gets into deadlocking issues, extra locks to hold the variables until the commit. Or perhaps we get into versioning of variables and then we buy problems of how to do rollbacks and retryies. I don't think we can do this immediately. Can you come up with the right API and/or hooks that are needed so that it might be retrofited? -- Chaim FrenkelNonlinear Knowledge, Inc. [EMAIL PROTECTED] +1-718-236-0183
Re: RFC 178 (v2) Lightweight Threads
> "DS" == Dan Sugalski <[EMAIL PROTECTED]> writes: DS> I'd definitely rather perl not do any sort of explicit user-level locking. DS> That's not our job, and there be dragons. Please explain how this is possible? Does this mean that without user specifying a lock, perl will allow a chaotic update pattern to be visible to the user? thread Athread B push(@foo, $bar); ++$bar; or $foo{$bar} = $baz; delete $foo{$bar++}; Will there be some sort of coherence here? -- Chaim FrenkelNonlinear Knowledge, Inc. [EMAIL PROTECTED] +1-718-236-0183
Re: RFC 136 (v2) Implementation of hash iterators
In message <[EMAIL PROTECTED]> Dan Sugalski <[EMAIL PROTECTED]> wrote: > Or have a "next" vtable function that takes a token and returns the next > entry in the variable. Each iterator keeps its own "current token" and the > variable's just responsible for figuring out what should get returned next. > > We could also have a "prev" entry to walk backwards, if we wanted. Well that's the kind of interface that I'd expect a hash iterator to be implemented in terms of, yes. As Chain pointed out though it doesn't solve the problem of freezing the state of a hash which is what that part of my RFC was attempting to do. Tom -- Tom Hughes ([EMAIL PROTECTED]) http://www.compton.nu/ ...Moderation in all things.
YAVTBL: yet another vtbl scheme
All - I fail to see the reason for imposing that all variables "know" how to perform ops upon themselves. An operation is separate from the data it operates on. Therefore, I propose the following vtbl scheme, with two goals: 1. that the minimal vtbl be just that, minimal 2. that it be possible (convenient) to override ops as needed First, a few basic types (these are sample only, and should be beaten on for cach-friendliness, etc. once a design is formalized). typedef struct _ovl { U32 ov_type; U32 ov_flags; void *ov_vtbl; void *ov_data; struct _ovl *ov_next; } OVERLOAD; typedef union { SCALAR_VTBL s; ARRAY_VTBL a; HASH_VTBL h; } SV_VTBL; typedef struct sv { void *sv_data; OVERLOAD *sv_magic; SV_VTBL *sv_vtbl; U32 sv_flags; /* and type (SV, AV, HV) */ (... GC stuff ... MT-safe stuff ...) } SV, *PMC; SV_VTBL, then, supports basic operations on perlish data types (get, store, and a few housekeeping things). Since noone (outside perl and libperl.so) should be directly calling vtbl functions, this makes it easy to put checks in that a variable is the appropriate type (ie, av_fetch will die if the variable is really a scalar). Here are what each data type should support (each get/set may require an argument giving a bit more detail (ie, U16 vs. I64, UTF8 vs. UTF16-bigendian, etc.)): SCALAR_VTBL: get_int get_string get_real get_ref num_sign /* positive or negative (or zero?)*/ num_is_integral set_int set_string set_real set_ref set_multival /* == perl5ish sv_setpv(sv...); sv_setiv(sv,...); SvPOK_on(sv); (esp this part) */ undef construct finalize ARRAY_VTBL: get_at set_at grow /* a hint on where we plan to put values, ie av->sv_vtbl.a.grow(bottom_ix, top_ix) */ size clear /* @av = (); */ undef /* undef @av; */ get_interator construct finalize HASH_VTBL: fetch store get_iterator /* not sure if these two are needed */ get_iterator_keys get_iterator_values clear undef size construct finalize In order to allow overriding of opcodes for, say, BigInts, several types of OVERLOAD are defined (4 basic types (flags in bottom byte of ov_type?) are defined, based on what flavor of vtbl is in ov_vtbl). These are OV_GET, OV_SET, OV_RANDOM, OV_OPS and are denoted in sv->sv_flags. The first three correspond to the perl5 GMG, SMG, and RMG. The last marks that the vtbl is an overload of one or more opcodes. Every op checks to see if it is overloaded, and if it is, calls that. Some ops don't need to (ie, vec() can just do a set_string and add an OVERLOAD for the bitwise ops). If necessary, additional subclasses of OV_OPS may be defined (ie, OV_NUMERIC, OV_STRING, OV_IO). -- BKS __ Do You Yahoo!? Yahoo! Mail - Free email you can access from anywhere! http://mail.yahoo.com/
Re: RFC 136 (v2) Implementation of hash iterators
> "DS" == Dan Sugalski <[EMAIL PROTECTED]> writes: >> This could be a lot more efficient than modifying the vtbl and filling >> up the stack with the keys. I really am suspicious of replacing the >> vtbl entry, there may be more than one thread working its way through >> the hash. DS> Or have a "next" vtable function that takes a token and returns the next DS> entry in the variable. Each iterator keeps its own "current token" and the DS> variable's just responsible for figuring out what should get returned next. DS> We could also have a "prev" entry to walk backwards, if we wanted. The problem to be handled is how to modify the hash/array while the iterator is live. (Multiple active iterators, in multiple threads.) Even my versioning suggestion is problematic. We have the problem of inconsistent views of the hash. Even if iterator A only looks at version A (e.g. generation number). What version should its changes apply toward? Or should we simply make an iterator lock out access until completed? How about this. Iterators lock the hash upon the first access and release it when either finished, reset or destroyed. Your mechanism, is more like a seek,read,tell sequence without any guarentees between access. -- Chaim FrenkelNonlinear Knowledge, Inc. [EMAIL PROTECTED] +1-718-236-0183
Re: RFC 130 (v5) Transaction-enabled variables for Perl6
On Tue, 5 Sep 2000 10:48:45 +0200, dLux wrote: >/--- On Mon, Sep 04, 2000 at 07:18:56PM -0500, Greg Rollins wrote: >| Will perl monitor the commit and rollback actions of transactions? >\--- > >What exactly you mean? And did you have to quote 500+ lines of the RFC just to add this one sentence? -- Bart.
Re: RFC 130 (v4) Transaction-enabled variables for Perl6
> >Doing this properly with data sources you completely control in a > >multi-access situation (read: with threads) is *hard*. > > Is it? > > 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); > } > > Now, "all" that needs to be taken care of, is make sure that the final > assignment from the localized and changed variables to their > outer-scoped counterparts happens in *one step*, i.e. no task switching > while this is going on. Well, that can't be done. (I assume that by 'task switching' you mean here 'thread switching') Or, if it can, it *shouldn't* be done. Threads run on their own until they yield, they decide to synchronize and/or join, or they exit. Note the "they decide". There is no central switchboard from where you can control 'your threads'. Sure, you could make all your threads to go through a central synchronization point 'often enough, say, in the op dispatch loop, but that's going to be rather costly. You can do all kinds of tricks with e.g. thread priorities, yes, but you cannot and you should not try to control trask switching. A 'yield' is the closest you can do, and that's just a kind note to the scheduler, not a command. > -- > Bart. -- $jhi++; # http://www.iki.fi/jhi/ # There is this special biologist word we use for 'stable'. # It is 'dead'. -- Jack Cohen
Re: RFC 130 (v4) Transaction-enabled variables for Perl6
On Tue, 05 Sep 2000 11:48:38 -0400, Dan Sugalski wrote: >>- two-phase commit handler, rollback coordinator (the above two is >> connected to this: very simple algorhythm!) > >Here's the killer. This is *not* simple. At all. Not even close. > >Doing this properly with data sources you completely control in a >multi-access situation (read: with threads) is *hard*. Is it? 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); } Now, "all" that needs to be taken care of, is make sure that the final assignment from the localized and changed variables to their outer-scoped counterparts happens in *one step*, i.e. no task switching while this is going on. -- Bart.
Re: RFC 130 (v4) Transaction-enabled variables for Perl6
/--- On Tue, Sep 05, 2000 at 11:48:38AM -0400, Dan Sugalski wrote: | >- two-phase commit handler, rollback coordinator (the above two | > is | > connected to this: very simple algorhythm!) | | Here's the killer. This is *not* simple. At all. Not even close. | | Doing this properly with data sources you completely control in a | multi-access situation (read: with threads) is *hard*. It requires | possibly | unbounded amounts of scratch space, a lot of cooperation with | anything that | accesses external data sources (like DBD::Oracle, say), and either | cooperation or lots of sophisticated programming for things that | stay | internal. (We would, for example, have to get very clever for code | that | accesses external libraries if they didn't support the transaction | interface, possibly snapshotting and later replacing all the | global state | they keep. Which may not be possible) All we need to do is similar to handling of the "local", and call the callbacks. I don't want the core to handle data sources which are NOT transaction-enabled. I only want to handle our objects and tied hashes (keep it simple and stupid). DBD::Oracle is not perl transaction-enabled, but it can support that if somebody write the required proper callbacks. I don't want the core to handle that DBD::Oracle needs to handle! The rule is that: IF you want to use transactions, USE transaction-enabled objects and tied interfaces! The commit is done with the following algorhithm: (this is done at the end of a block where a transaction has finishes) - gather variables that are transaction-enabled. - finds TIE_PREPARE and PREPARE callbacks. - Call them - If any of that returns 0, then we call all TIE_ROLLBACK and ROLLBACK callbacks - If all returns with 1, then we call all TIE_COMMIT and COMMIT callbacks I don't want to snapshot any module that doesn't support transactions. This must not be the goal. It's impossible, I agree. But we can extend the transaction-support by modules which can handle transactions later. Look at the very simple example in the RFC130 v5. This is file-handler (ties the content of a file to a hash), and does the locking, reading, two-phase commit, etc in perl. (this is not perfect, because "link -f" is not atomic, but very near to that). There are companies that builds mission-critical systems, and they will build objects for their own data-storage systems. Not all data are in databases. Someone may use text files mixed with database tables (imagine a freemail system: if an error occured when deleting the mail from the mailbox, we must not decrease the mail-count). So: we don't want to handle what is impossible. Look how good it is even if we use the transaction-enabled modules. Allwecando ifsomebodydoesn'tsupportthe transaction-environment is emulating the rollback and commit with FETCH-es and STORE-s. We don't have a chance to emulate that with objects. That's the limitations. | >then all things are very | >straightforward, aren't they? It is _not_ complicated at all. It | >is | >all Perlish! | | This is far from straightforward. Keen, yes, but very far from | straightforward. It would also add a lot of code to the core, and | possibly | place some heavy demands on the resources of machines running perl | code. If we do all you imagine, yes, but we only want to implement what is to be implemented in the core, and this is not more than the 2pc alg. \--- dLux -- This Message is Powered by VI
Re: RFC 178 (v2) Lightweight Threads
At 10:57 PM 9/4/00 -0400, Chaim Frenkel wrote: > > "SWM" == Steven W McDougall <[EMAIL PROTECTED]> writes: >PRL> All threads share the same global variables > >> > >> _All_ or only as requested by the user (ala :shared)? > >SWM> All. > >Dan has gone through this with perl5 and he really would rather not >have to go through that. He would like the amount of data that needs >protection reduced. I don't mind if package variables are all shared by default, or if there's a simple way to share them all at thread creation time. We do tell people to not use package variables so if access to them is slow, well, no biggie. >You are also creating problems when I don't want mediation. What if >I know better than perl and I want to us a single item to protect >a critical section? I'd definitely rather perl not do any sort of explicit user-level locking. That's not our job, and there be dragons. >SWM> Data coherence just means that the interpreter won't crash or corrupt >SWM> its internal data representation. RFC178 uses the term *data >SWM> synchronization* for coordinating access to multiple variables between >SWM> threads. > >Then this RFC seems to be confusing two things. This is for -internals >we don't even have any internal structures, so how can you be protecting >them. If you are working at the language level this is the wrong forum. Perl will guarantee coherence for any internal data structure that's shared between threads. No core dumps because lock()'s not thread-safe here... > >> Perhaps, I'm archaic, but I really wouldn't mind if the thread model > >> basically copied the fork() model and required those variable that have > >> to live across threads to be marked as :shared. > >SWM> Sigh...if that's the best I can get, I'll take it. > >I'm not the decisor here, I'm just pointing out another way to look >at the problem. I really don't think you want to have _all_ variable >actually visible. Even if they were, you will most likely have only >a limited number that you want visible. Reducing the number of visible items is good, because it means perl doesn't have to keep its internal locks on thread-specific data elements. Perl can, to some extent, intuit which items aren't visible and skip making them shared, but that requires what's likely to be rather expensive flow analysis. (Which we might do anyway, sort of, but I wouldn't count on it) Taking out mutexes isn't free. Cheap, yes, but not free, and those 20ns mutex aquisition and releases do add up after a while. Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: RFC 136 (v2) Implementation of hash iterators
At 08:18 PM 9/4/00 -0400, Chaim Frenkel wrote: > > "PRL" == Perl6 RFC Librarian <[EMAIL PROTECTED]> writes: > >PRL> =head2 Freezing state for keys and values efficiently > >PRL> I believe this problem can be solved by using the vtable for the >PRL> hash to wrap any mutating functions with a completion routine that >PRL> will advance the iterator to completion, creating a temporary list >PRL> of copied keys/values that it can then continue to iterate over. > >Have versioned hash entries. Iterators would know what version of the >hash they are operating on. > >This could be a lot more efficient than modifying the vtbl and filling >up the stack with the keys. I really am suspicious of replacing the >vtbl entry, there may be more than one thread working its way through >the hash. Or have a "next" vtable function that takes a token and returns the next entry in the variable. Each iterator keeps its own "current token" and the variable's just responsible for figuring out what should get returned next. We could also have a "prev" entry to walk backwards, if we wanted. Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: RFC 130 (v4) Transaction-enabled variables for Perl6
At 01:42 AM 9/4/00 +0200, dLux wrote: >What it needs in the core is pretty small btw: I think you underestimate things here a tad... >- a new keyword, which is similar to "local" Okay, that's small. >- some extension to the TIE interface (some new callbacks) As is this. >- some extension to the object interface (new callbacks) And this. >- lock/mutex handler This could piggy-back on the threaded code stuff. >- two-phase commit handler, rollback coordinator (the above two is > connected to this: very simple algorhythm!) Here's the killer. This is *not* simple. At all. Not even close. Doing this properly with data sources you completely control in a multi-access situation (read: with threads) is *hard*. It requires possibly unbounded amounts of scratch space, a lot of cooperation with anything that accesses external data sources (like DBD::Oracle, say), and either cooperation or lots of sophisticated programming for things that stay internal. (We would, for example, have to get very clever for code that accesses external libraries if they didn't support the transaction interface, possibly snapshotting and later replacing all the global state they keep. Which may not be possible) >then all things are very >straightforward, aren't they? It is _not_ complicated at all. It is >all Perlish! This is far from straightforward. Keen, yes, but very far from straightforward. It would also add a lot of code to the core, and possibly place some heavy demands on the resources of machines running perl code. Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: RFC 178 (v1) Lightweight Threads
> "SWM" == Steven W McDougall <[EMAIL PROTECTED]> writes: >> my $a; >> >> Perl simply ignores locking. Thread gets the value of the winner >> in a race condition. Perl does _not_ crash and burn. Internal >> structures, mallocs, and accesses are properly mutexed. SWM> I don't understand this. SWM> Is $a shared between threads or isn't it? Thinko. You are correct. Changes are invisible to the other thread. SWM> If it is, then these two statements seem directly contradictory: SWM> - Perl simply ignores locking. SWM> - Internal structures, mallocs, and accesses are properly mutexed I think we are still in mutual misunderstanding. I am only addressing what the _user_ sees. Not what perl will do internally. I'm working under the assumption that -internals will do whatever it has to, to keep perl properly functioning in the face of threads. -- Chaim FrenkelNonlinear Knowledge, Inc. [EMAIL PROTECTED] +1-718-236-0183
Re: Profiling
<[EMAIL PROTECTED]> writes: >> >> Anyone surprised by the top few entries: > >Nope. It looks close to what I saw when I profiled perl 5.004 and 5.005 >running over innlog.pl and cleanfeed. The only difference is the method >stuff, since neither of those were OO apps. The current Perl seems to >spend most of its time in the op dispatch loop and in dealing with >internal data structures. What initially surprised me is why the op-despatch loop spends so long in 'self' code when there is so little of it. My assumption is this is where we see the "cache miss" time. -- Nick Ing-Simmons <[EMAIL PROTECTED]> Via, but not speaking for: Texas Instruments Ltd.
Re: RFC 130 (v5) Transaction-enabled variables for Perl6
/--- On Mon, Sep 04, 2000 at 07:18:56PM -0500, Greg Rollins wrote: | Will perl monitor the commit and rollback actions of transactions? \--- What exactly you mean? dLux -- This message is READ-ONLY
Re: RFC 130 (v5) Transaction-enabled variables for Perl6
Will perl monitor the commit and rollback actions of transactions? - Original Message - From: "Perl6 RFC Librarian" <[EMAIL PROTECTED]> To: <[EMAIL PROTECTED]> Cc: <[EMAIL PROTECTED]> Sent: Monday, September 04, 2000 4:35 PM Subject: RFC 130 (v5) Transaction-enabled variables for Perl6 > This and other RFCs are available on the web at > http://dev.perl.org/rfc/ > > =head1 TITLE > > Transaction-enabled variables for Perl6 > > =head1 VERSION > > Maintainer: Szabó, Balázs <[EMAIL PROTECTED]> > Date: 17 Aug 2000 > Last Modified: 02 Sep 2000 > Mailing List: [EMAIL PROTECTED] > Version: 5 > Number: 130 > Status: Developing > > =head1 ABSTRACT > > Transactions are quite important in a database-enabled application. > Professional database systems have transaction-handling inside, but there are > only a few laguage out there, what supports transactions in variable level. > > In this RFC we will look at how these variables would look like in perl6. > > We would like to choose the keyword we want to use for this purposes, because > there are a lot of alternatives. > > =head1 WHAT'S NEW IN VERSION 5 > > =over 4 > > =item * > > TRANSACTION-ENABLED TIED VARIABLE EXAMPLE added > > =item * > > BEGIN_TRANSACTION and TIE_BEGIN_TRANSACTION added > > =item * > > TIE* renamed to TIE_* > > =item * > > CHANGES moved to the end of the RFC > > =item * > > Added alternatives to "trans" > > =head1 DESCRIPTION > > In short, we have "local" keyword, which changes a value of a variable for only > the runtime of the current scope. The transaction-enabled variables should > start up like "local", but IF the currenct scope reaches at the end, it then > copied into the global one. > > We need to get a keyword to mark a variable transaction-enabled. I chosed > "trans" in this ducument, but other suggestions are welcome. Possible > alternatives are: > > transaction > transactional > acid > atomic > onsuccess > consistent > > The final decision will be made by the porters, I use "trans" in this > document. > > Preferred syntax: > > sub trans_test { my ($self,@params)=@_; > trans $self->{value}=$new_value; > > # ... > > die "Error occured" if $some_error; > > function_call(...) > > # ... > > } ; > > Meaning (in semi perl5 syntax): > > sub trans_test { > local $self->{value}=$new_value; > > # ... > > die "Error occured" if $ome_erre; > > function_call(...) > > # ... > > global $self->{value}=$self->{value}; > }; > > If we want to gain more control and want to maintain easy syntax, we can use > another pragma, which sets up the attributes of the isolation of transaction > data. I think the "transaction" pragma could be a good name: > > use transaction (mode => 'lock', timeout=>6000); > > Parameters for "use transaction": > > =over 4 > > =item mode > > can be: > > =over 4 > > =item simple > > No blocking, concurrency control (default). > > In a not-threaded environment this causes minimal overhead, and no locking > overhead at all. > > =item lock > > Explicitly lock the accessed variables. (shared and exclusive locks used > between threads). > > =item version > > This is simlar to the postgres' multi-version concurrency control. It requires > more memory, but has a less chance to get into deadlock. > > =back > > =item timeout > > Timeout in ms until we wait for the lock. 0 means nonblocking. If the timeout > reached, the system throws an exception. > > =item isolation > > Transaction isolation level. This can be: > > =over 4 > > =item 0 > > Read uncommitted > > =item 1 > > Read committed (default) > > =item 2 > > Repeatable read > > =item 3 > > Serializable. > > =back > > PostgreSQL implements only 1 and 3 AFAIK, so I think we could implment only > those levels. Then 0 and 2 will be equal to 1 and 3, but we could keep the > place for a future implementation. > > See the postgreSQL documentation for the details. > > =back > > =head2 Two phase commit > > Two phase commit is the common way to deal with distributed transactions. Perl > need an interface to objects and tied variables to deal with these to become a > reliable transaction-handler. You can choose to implement these features in > your object and your tied variable. If you don't do that, perl will give you a > rough default. > > At the end of the transaction, 2 different thing can happen: rollback or > commit. When rollback occured, all the transaction variables must be rolled > back. In commit, a two-phase commit procedure has been started. > > The first phase is preparing to the commit: check the resources, allocates > resources to the commit, flushes caches, etc. After that it can decide wheter > you can do a commit or not. If all participants send "yes", then the commit > phase begins: the coordinator sends "commit" messages to the participants, and > the transaction finishes. If any of the participants in the "prepare" phase > sends a false value, then the whole transaction need to be rolled