D - Transactions
- nicO (19/19) Aug 19 2001 Few times ago, i will see how to use C long jump to restore a crashing
- Walter (3/22) Aug 21 2001 How does this differ from try-catch-finally?
- Russell Bornschlegel (31/49) Aug 21 2001 Walter--
- nicO (9/67) Aug 22 2001 In fact, it's hard to do it with IO function. That sure. But maybe such
- Eric Gerlach (33/46) Aug 25 2001 I'd never thought of it before, even though I do lots of work with
Few times ago, i will see how to use C long jump to restore a crashing program. So i rediscover the concept of transaction. I think it could be usefull to be implementent in the language built-in. You need at least 3 new keys words. BEGIN_TRANSACTION, ABORT_TRANSACTION, END_TRANSACTION The goal is to create a protected environnement, if the transaction failed for what ever raison the initial state (just before the begin_transaction) is restore. We could imagine in a program with GUI, each fonction under each menu are a transaction so instead of a core dump you just have an error message, if the procedure failed. It could be interresting for Deamon, too, to avoid DoS. I think i could be easly done as for fork() system call are made under Linux. Each data section became read-only, if a write occur it's trap. Then the system use an other page and copy the initial value and then make the write. If the transaction failed the page is "forget". If it reach the end_transaction, the memory page are swaped and the old one is given back to the free memory tank. I think it's an interresting way to write more secure program. nicO
Aug 19 2001
How does this differ from try-catch-finally? "nicO" <nicolas.boulay ifrance.com> wrote in message news:3B8016F2.E5DDCD04 ifrance.com...Few times ago, i will see how to use C long jump to restore a crashing program. So i rediscover the concept of transaction. I think it could be usefull to be implementent in the language built-in. You need at least 3 new keys words. BEGIN_TRANSACTION, ABORT_TRANSACTION, END_TRANSACTION The goal is to create a protected environnement, if the transaction failed for what ever raison the initial state (just before the begin_transaction) is restore. We could imagine in a program with GUI, each fonction under each menu are a transaction so instead of a core dump you just have an error message, if the procedure failed. It could be interresting for Deamon, too, to avoid DoS. I think i could be easly done as for fork() system call are made under Linux. Each data section became read-only, if a write occur it's trap. Then the system use an other page and copy the initial value and then make the write. If the transaction failed the page is "forget". If it reach the end_transaction, the memory page are swaped and the old one is given back to the free memory tank. I think it's an interresting way to write more secure program. nicO
Aug 21 2001
Walter wrote:How does this differ from try-catch-finally? "nicO" <nicolas.boulay ifrance.com> wrote in message news:3B8016F2.E5DDCD04 ifrance.com...Walter-- Things within the try block that executed before the exception fired aren't "undone" with try-catch-finally; the usual database sense of "transaction" connotes atomicity: it requires that either everything within the transaction succeeds, or that nothing happens: transaction { if (take_money_out_of_walters_account() == FAILURE) { abort_transaction; } if (put_money_into_russells_account() == FAILURE) { abort_transaction; } } Here, if the money comes out of your account successfully, then for whatever reason, it can't be put into my account, we "roll back" the whole transaction and the money goes back into your account. I don't think that this can be done in a C-like language, not in the general case of undoing any conceivable action.Few times ago, i will see how to use C long jump to restore a crashing program. So i rediscover the concept of transaction. I think it could be usefull to be implementent in the language built-in. You need at least 3 new keys words. BEGIN_TRANSACTION, ABORT_TRANSACTION, END_TRANSACTIONAny function called during such a transaction that had side effects would be problematic with a scheme like this. This is only useful for rolling back changes to process local memory, and that's doable with a class object that's "double-buffered" -- i.e. it keeps "current state" and "state-in-progress," and once "state-in-progress" is updated safely, the buffers are swapped atomically. -RI think i could be easly done as for fork() system call are made under Linux. Each data section became read-only, if a write occur it's trap. Then the system use an other page and copy the initial value and then make the write. If the transaction failed the page is "forget". If it reach the end_transaction, the memory page are swaped and the old one is given back to the free memory tank.
Aug 21 2001
Russell Bornschlegel a écrit :Walter wrote:In fact, it's hard to do it with IO function. That sure. But maybe such function couldn't be allowed inside transaction. Or compiler could detect that and double buffer each write. The problem are for read. I think it could be done for file (like for data base at the beginning of the transaction). Maybe IO function should be rewrite. Concerning all access to the network, i understand that couldn't be handel. But that's a big beginning. nicOHow does this differ from try-catch-finally? "nicO" <nicolas.boulay ifrance.com> wrote in message news:3B8016F2.E5DDCD04 ifrance.com...Walter-- Things within the try block that executed before the exception fired aren't "undone" with try-catch-finally; the usual database sense of "transaction" connotes atomicity: it requires that either everything within the transaction succeeds, or that nothing happens: transaction { if (take_money_out_of_walters_account() == FAILURE) { abort_transaction; } if (put_money_into_russells_account() == FAILURE) { abort_transaction; } } Here, if the money comes out of your account successfully, then for whatever reason, it can't be put into my account, we "roll back" the whole transaction and the money goes back into your account. I don't think that this can be done in a C-like language, not in the general case of undoing any conceivable action.Few times ago, i will see how to use C long jump to restore a crashing program. So i rediscover the concept of transaction. I think it could be usefull to be implementent in the language built-in. You need at least 3 new keys words. BEGIN_TRANSACTION, ABORT_TRANSACTION, END_TRANSACTIONAny function called during such a transaction that had side effects would be problematic with a scheme like this. This is only useful for rolling back changes to process local memory, and that's doable with a class object that's "double-buffered" -- i.e. it keeps "current state" and "state-in-progress," and once "state-in-progress" is updated safely, the buffers are swapped atomically.I think i could be easly done as for fork() system call are made under Linux. Each data section became read-only, if a write occur it's trap. Then the system use an other page and copy the initial value and then make the write. If the transaction failed the page is "forget". If it reach the end_transaction, the memory page are swaped and the old one is given back to the free memory tank.-R
Aug 22 2001
Russell Bornschlegel a écrit : <snip> In fact, it's hard to do it with IO function. That sure. But maybe such function couldn't be allowed inside transaction. Or compiler could detect that and double buffer each write. The problem are for read. I think it could be done for file (like for data base at the beginning of the transaction). Maybe IO function should be rewrite. Concerning all access to the network, i understand that couldn't be handel. But that's a big beginning. nicOI'd never thought of it before, even though I do lots of work with databases, but this could be an interesting idea. IMHO, it would be very, very difficult to implement with the syntax you suggest, however. I think if a more complex syntax were used it would be easier to implement it. Consider a syntax similar to Java's 'synchronised': int foo(int a) transaction { return perform_global_operation(a); } rollback { undo_global_operation(a); } void main() { transaction { if (3 == foo(2)) { rollback; } /* do more stuff, it's okay */ } } You could only have functions which support transactions within a transaction block. The 'rollback' statement calls the rollback portions of the function calls (in reverse call-order?), and they are responsible for undoing what they did. Now, I don't think that this fits into the scheme of D, but it's a really neat idea. I wouldn't mind seeing it if it's not too difficult to implement though. It could be really useful. Eric
Aug 25 2001
Eric Gerlach wrote:Well this topic doesn't belong here, but I like it. How about a way of mark data to be used in the transaction and let the compiler deal with make copies and restoring values. int x, y, z; string m, n, o; // do cool things transaction{ // too long of a key word mark x; // call it mark because preserve is also too long mark y; // We want to be able to restore these values mark m, n; // we might as well allow marking multiples z = mess_with(m, x); // we won't preserve z if(z != GOOD_THINGS){ o = "first operation failed"; // o isn't preserved rollback(o); // restore uncommitted values and throw // RollBack exception with o as message } commit(m); // commit only the change to m so far (not x) z = mess_with(n, y); if(z != GOOD_THING){ rollback(o="second operation bombed"); } commit(); // commit all marked vars in this transaction block. // I don't know how to do "all mark vars in this // transaction and enclosing transactions. Maybe // named transaction blocks? }catch(RollBack e){ log("Bad things man [" + string(z) + "]:" + e.msg()); } Uncommitted marked variables would automatically roll back when leaving the transaction block without a call to rollback, but I can decide if an exception should be throw then. Mark would probably require types to have some form of duplication method so it can copy more than just a reference. The transaction block is really the only thing special here. Rollback() could be a function. Mark would probably be special unless generic programming is supported well enough, but even then I guess rollback and mark would need access to some special context info introduced by any enclosing transaction blocks. In any case, this is all academic. DanRussell Bornschlegel a écrit : <snip> In fact, it's hard to do it with IO function. That sure. But maybe such function couldn't be allowed inside transaction. Or compiler could detect that and double buffer each write. The problem are for read. I think it could be done for file (like for data base at the beginning of the transaction). Maybe IO function should be rewrite. Concerning all access to the network, i understand that couldn't be handel. But that's a big beginning. nicOI'd never thought of it before, even though I do lots of work with databases, but this could be an interesting idea. IMHO, it would be very, very difficult to implement with the syntax you suggest, however. I think if a more complex syntax were used it would be easier to implement it. Consider a syntax similar to Java's 'synchronised': int foo(int a) transaction { return perform_global_operation(a); } rollback { undo_global_operation(a); } void main() { transaction { if (3 == foo(2)) { rollback; } /* do more stuff, it's okay */ } } You could only have functions which support transactions within a transaction block. The 'rollback' statement calls the rollback portions of the function calls (in reverse call-order?), and they are responsible for undoing what they did. Now, I don't think that this fits into the scheme of D, but it's a really neat idea. I wouldn't mind seeing it if it's not too difficult to implement though. It could be really useful. Eric
Aug 25 2001
Dan Hursh a écrit :Eric Gerlach wrote:If you put many commit, in fact you do 2 separate transaction. Transaction look like synchronise because it should do the same things, too (atomic behavior). So commit could be down at the end of the transaction. As said before, rollback memory (variable,...) is in fact very easy. As maid for fork() under linux, all memory page are marked read-only, if a write occure, it is done in an other memory page. Then, if the transaction is abort, the new pages are destroy. If it commit, the old page is destroy and the new pages are used. No need of rollback function, it save a lot of code to write. Rollback function used as this look like exception handler. nicOWell this topic doesn't belong here, but I like it. How about a way of mark data to be used in the transaction and let the compiler deal with make copies and restoring values. int x, y, z; string m, n, o; // do cool things transaction{ // too long of a key word mark x; // call it mark because preserve is also too long mark y; // We want to be able to restore these values mark m, n; // we might as well allow marking multiples z = mess_with(m, x); // we won't preserve z if(z != GOOD_THINGS){ o = "first operation failed"; // o isn't preserved rollback(o); // restore uncommitted values and throw // RollBack exception with o as message } commit(m); // commit only the change to m so far (not x) z = mess_with(n, y); if(z != GOOD_THING){ rollback(o="second operation bombed"); } commit(); // commit all marked vars in this transaction block. // I don't know how to do "all mark vars in this // transaction and enclosing transactions. Maybe // named transaction blocks? }catch(RollBack e){ log("Bad things man [" + string(z) + "]:" + e.msg()); } Uncommitted marked variables would automatically roll back when leaving the transaction block without a call to rollback, but I can decide if an exception should be throw then. Mark would probably require types to have some form of duplication method so it can copy more than just a reference. The transaction block is really the only thing special here. Rollback() could be a function. Mark would probably be special unless generic programming is supported well enough, but even then I guess rollback and mark would need access to some special context info introduced by any enclosing transaction blocks. In any case, this is all academic.Russell Bornschlegel a écrit : <snip> In fact, it's hard to do it with IO function. That sure. But maybe such function couldn't be allowed inside transaction. Or compiler could detect that and double buffer each write. The problem are for read. I think it could be done for file (like for data base at the beginning of the transaction). Maybe IO function should be rewrite. Concerning all access to the network, i understand that couldn't be handel. But that's a big beginning. nicOI'd never thought of it before, even though I do lots of work with databases, but this could be an interesting idea. IMHO, it would be very, very difficult to implement with the syntax you suggest, however. I think if a more complex syntax were used it would be easier to implement it. Consider a syntax similar to Java's 'synchronised': int foo(int a) transaction { return perform_global_operation(a); } rollback { undo_global_operation(a); } void main() { transaction { if (3 == foo(2)) { rollback; } /* do more stuff, it's okay */ } } You could only have functions which support transactions within a transaction block. The 'rollback' statement calls the rollback portions of the function calls (in reverse call-order?), and they are responsible for undoing what they did. Now, I don't think that this fits into the scheme of D, but it's a really neat idea. I wouldn't mind seeing it if it's not too difficult to implement though. It could be really useful. EricDan
Aug 26 2001