[transact] code in sandbox

Hi, I haven't had much time lately, and that's not going to change to next couple of weeks, so I've uploaded what I have so far to the sandbox: https://svn.boost.org/svn/boost/sandbox/transaction/boost/transact/ what's new: *** basic_transaction_manager: - now supports all kinds of combinations of commits, like we've discussed, including one-phase/transient two-phase, persistent two-phase. no logging/recovery yet. - lazy and non-lazy transaction construction, user-configurable *** simple_transaction_manager: a transaction manager supporting only one resource. basic_tranaction_manager includes a lot of MPL/fusion and the logging infrastrucure, none of which is needed for only one resource. this is intended to be the default transaction manager when one of our libraries is used on its own. *** logging infrastructure: to be used by basic_transaction_manager for its distributed transaction log, and optionally by resource managers that need logging (so it is part of the public interface!) - olog_files: maintaining log files without knowing its contents, manual log rolling - otransaction_log_files: same as olog_files, but automatic log rolling based on transactions - olog: writes to olog_files, aware of log entries - olog_buffer: same interface as olog, but buffers log entries locally and only accesses the log when the internal buffer overflows. - TODO: ilog_files/ilog to read/recover from logs. code is there, but not migrated to "transact". - TODO: interleaved_ologs/..., providing multiple olog interfaces so different resource managers can share a log, as we've discussed. *** new syntax for transaction scopes: syntax changed from: atomic{ ... }retry; to do atomic{ }commit(); I prefer that syntax because it resembles the do{}while(...) syntax. downside is that it conflicts with transaction::commit() if the user chooses to define BOOST_TRANSACT_COMMIT to "commit" (as is done above). *** TODO object_access not migrated to "transact" yet. utility functions for resource managers to serialize/clone/compare/... objects. regards, Stefan

Hi Stefan, ----- Original Message ----- From: <strasser@uni-bremen.de> To: "Bob Walters" <bob.s.walters@gmail.com>; "vicente.botet" <vicente.botet@wanadoo.fr> Cc: <boost@lists.boost.org> Sent: Tuesday, February 09, 2010 2:54 PM Subject: [transact] code in sandbox
Hi,
I haven't had much time lately, and that's not going to change to next couple of weeks, so I've uploaded what I have so far to the sandbox:
https://svn.boost.org/svn/boost/sandbox/transaction/boost/transact/
I'm too in the same case. Too much work :(.
what's new:
*** basic_transaction_manager: - now supports all kinds of combinations of commits, like we've discussed, including one-phase/transient two-phase, persistent two-phase. no logging/recovery yet. - lazy and non-lazy transaction construction, user-configurable
*** simple_transaction_manager: a transaction manager supporting only one resource. basic_tranaction_manager includes a lot of MPL/fusion and the logging infrastrucure, none of which is needed for only one resource. this is intended to be the default transaction manager when one of our libraries is used on its own.
Yes, at a first glance this could allow possible optimizations.
*** logging infrastructure: to be used by basic_transaction_manager for its distributed transaction log, and optionally by resource managers that need logging (so it is part of the public interface!)
- olog_files: maintaining log files without knowing its contents, manual log rolling - otransaction_log_files: same as olog_files, but automatic log rolling based on transactions - olog: writes to olog_files, aware of log entries - olog_buffer: same interface as olog, but buffers log entries locally and only accesses the log when the internal buffer overflows. - TODO: ilog_files/ilog to read/recover from logs. code is there, but not migrated to "transact". - TODO: interleaved_ologs/..., providing multiple olog interfaces so different resource managers can share a log, as we've discussed.
*** new syntax for transaction scopes: syntax changed from: atomic{ ... }retry;
to
do atomic{
}commit();
I prefer that syntax because it resembles the do{}while(...) syntax. downside is that it conflicts with transaction::commit() if the user chooses to define BOOST_TRANSACT_COMMIT to "commit" (as is done above).
Maybe we can preserv both and see how the user react. Take in account that as macros must be prefixed, the preceding will look like BOOST_TRANSACT_ATOMIC { ... } BOOST_TRANSACT_RETRY; and do BOOST_TRANSACT_ATOMIC { }commit();
*** TODO object_access not migrated to "transact" yet. utility functions for resource managers to serialize/clone/compare/... objects.
regards,
Stefan
Thanks for the work you have done. I'll come back when I'll have more available time. Best, Vicente

Zitat von "vicente.botet" <vicente.botet@wanadoo.fr>:
*** new syntax for transaction scopes: syntax changed from: atomic{ ... }retry;
to
do atomic{
}commit();
I prefer that syntax because it resembles the do{}while(...) syntax. downside is that it conflicts with transaction::commit() if the user chooses to define BOOST_TRANSACT_COMMIT to "commit" (as is done above).
Maybe we can preserv both and see how the user react.
the user can easily create the old syntax using the existing macros: #define atomic do BOOST_TRANSACT_ATOMIC #define retry BOOST_TRANSACT_COMMIT()

----- Original Message ----- From: <strasser@uni-bremen.de> To: "vicente.botet" <vicente.botet@wanadoo.fr> Cc: "Bob Walters" <bob.s.walters@gmail.com>; <boost@lists.boost.org> Sent: Thursday, February 11, 2010 6:01 AM Subject: Re: [transact] code in sandbox
Zitat von "vicente.botet" <vicente.botet@wanadoo.fr>:
*** new syntax for transaction scopes: syntax changed from: atomic{ ... }retry;
to
do atomic{
}commit();
I prefer that syntax because it resembles the do{}while(...) syntax. downside is that it conflicts with transaction::commit() if the user chooses to define BOOST_TRANSACT_COMMIT to "commit" (as is done above).
Maybe we can preserv both and see how the user react.
the user can easily create the old syntax using the existing macros:
#define atomic do BOOST_TRANSACT_ATOMIC #define retry BOOST_TRANSACT_COMMIT()
Hi, with your macro definitions #define BOOST_TRANSACT_BASIC_ATOMIC(TXMGR) \ { \ try{ \ boost::transact::basic_transaction<TXMGR> ___tx; #define BOOST_TRANSACT_BASIC_COMMIT(TXMGR) \ } \ ___tx.commit_(); \ }catch(boost::transact::isolation_exception &i){ \ i.unwind<TXMGR>(); \ continue; \ } \ }while(false); the catch has no access to the transaction variable as it out of scope (already destructed). Some times it is interesting to increase the priority of a transaction to avoid starvation. In this case we need to be able to access the transaction. On Boost.STM we have developed some macros (see stm/branches/vbe/boost/stm/language_like.hpp) . Next follows the Transact adaptation of some of them. #define BOOST_TRANSACT_BASIC_ATOMIC(TXMGR, TX)\ for (boost::transact::basic_transaction<TXMGR> TX; \ ! TX.committed() && TX.restart_if_not_inflight(); \ TX.no_throw_commit()) try #define BOOST_TRANSACT_BASIC_RETRY(TXMGR, TX) \ catch (boost::transact::isolation_exception &i) {} #define BOOST_TRANSACT_BASIC_BEFORE_RETRY(TXMGR, TX) catch (boost::transact::isolation_exception &i) #define BOOST_TRANSACT_BASIC_RETHROW(TXMGR, TX, E) \ catch (E&) {(TX).commit(); throw;} #define BOOST_TRANSACT_BASIC_ABORT_ON_EXCEPTION(TXMGR, TX, E) \ catch (E&) {(TX).force_to_abort();} BTW, what unwind does? Could you explain the problem it intend to solve. With these macros the user will be able to // retry when an a isolation exception occurs BOOST_TRANSACT_ATOMIC(_) { } BOOST_TRANSACT_RETRY(_) // increase the priority of the transaction before restart the transaction when an a isolation exception occurs BOOST_TRANSACT_ATOMIC(_) { } BOOST_TRANSACT_BEFORE_RETRY(_) {_.increase_priority(); }. // or retry when an a isolation exception occurs and retrow the exception Ex BOOST_TRANSACT_ATOMIC(_) { ... } BOOST_TRANSACT_RETRY BOOST_TRANSACT_RETHROW(_, Ex) // or retry when an a isolation exception occurs and abort when the exception Ex occurs BOOST_TRANSACT_ATOMIC(_) { ... } BOOST_TRANSACT_RETRY BOOST_TRANSACT_ABORTON_EXCEPTION(_, Ex) There are a lot of other macros. I'll present all these and more as for example how to exit succesfully from a transaction block (return, break, continue or goto) at BoostCon. Let me know if you want I add them to Boost.Transact; this could be my little contrinution to Boost.Transact for the moment. Best, Vicente

Zitat von \"vicente.botet\" <vicente.botet@wanadoo.fr>:
the catch has no access to the transaction variable as it out of scope (already destructed). Some times it is interesting to increase the priority of a transaction to avoid starvation. In this case we need to be able to access the transaction.
wouldn\'t that then be a new transaction with an increased priority, after the first transaction failed? why do you keep the transaction object and restart it instead of just creating a new transaction object (possibly with an increased priority)?
BOOST_TRANSACT_ATOMIC(_) {
} BOOST_TRANSACT_BEFORE_RETRY(_) {_.increase_priority(); }.
since setting a priority would be resource manager specific, you\'d have to access the resource transaction: TxMgr::resource_transaction(TxMgr::active()).set_priority(...) (or a simpler shortcut defined by your library, but my point is that it can\'t be a member function of basic_transaction)
On Boost.STM we have developed some macros (see stm/branches/vbe/boost/stm/language_like.hpp) . Next follows the Transact adaptation of some of them.
#define BOOST_TRANSACT_BASIC_ATOMIC(TXMGR, TX)\\ for (boost::transact::basic_transaction<TXMGR> TX; \\ ! TX.committed() && TX.restart_if_not_inflight(); \\ TX.no_throw_commit()) try
#define BOOST_TRANSACT_BASIC_RETRY(TXMGR, TX) \\ catch (boost::transact::isolation_exception &i) {}
#define BOOST_TRANSACT_BASIC_BEFORE_RETRY(TXMGR, TX) catch (boost::transact::isolation_exception &i)
#define BOOST_TRANSACT_BASIC_RETHROW(TXMGR, TX, E) \\ catch (E&) {(TX).commit(); throw;}
#define BOOST_TRANSACT_BASIC_ABORT_ON_EXCEPTION(TXMGR, TX, E) \\ catch (E&) {(TX).force_to_abort();}
could you explain a situation in which you\'d use those other macros? to me, the macros are a simplified syntax for the most common use case, not a syntax which covers every possible use case you could think of. at some point I think the macros loose their benefit and you might just as well write the loop yourself. e.g. if you need to execute custom code on retry. if you think some of those macros would be widely used, please explain which ones and what the functions in the macros like no_throw_commit/force_to_abort etc. do. some of this seem resource-manager specific again.
BTW, what unwind does? Could you explain the problem it intend to solve.
unwinding nested transaction stack. an isolation exception thrown inside a nested transaction might e.g. make it necessary to rethrow it until the outermost transaction is destroyed. for example: do atomic{ loc<pers_type> pers_obj=...; do atomic{ //pers_obj is deleted by another transaction at this point cerr << pers_obj->value; //throws }commit(); }commit(); if the isolation exception would only cause the innermost transaction to be repeated, it would be repeated forever, since pers_obj is not coming back. via unwind() the resource manager throwing the exception can control up to which transaction on the stack the isolation_exception is rethrown. see exception.hpp.
There are a lot of other macros. I\'ll present all these and more as for example how to exit succesfully from a transaction block (return, break, continue or goto) at BoostCon.
justin mentioned a to-be-released paper about that some time ago, has this been published in the meantime?
Let me know if you want I add them to Boost.Transact;
if we can identify another common use case that is not resource manager specific, sure. if it is Boost.STM-specific, your library is the right place to define the macro.
participants (2)
-
strasser@uni-bremen.de
-
vicente.botet