Boost logo

Boost :

Subject: Re: [boost] [std_rdb] [rdb] 0.0.09
From: vicente.botet (vicente.botet_at_[hidden])
Date: 2009-10-01 02:06:48


Hi,

First, thanks for trying to provide yet another relational database C++ front-end library.

I have some general remarks. As the query language the DSLE emmulates is SQL, dont you think that you could put it in a specific sql directory and namespace. Other query language can be provided as Joel has already shown.

More inline ...

----- Original Message -----
From: "Stewart, Robert" <Robert.Stewart_at_[hidden]>
To: "List to discuss standard rdb" <std_rdb_at_[hidden]>; <boost_at_[hidden]>
Sent: Wednesday, September 30, 2009 5:37 PM
Subject: Re: [boost] [std_rdb] [rdb] 0.0.09

>
> Jean-Louis Leroy wrote:
>>
>> my plan is
>> to support native bindings. In ODBC a transaction looks like this :
>>
>> set autocommit off
>> do work
>> commit or roll back
>> do work
>> commit or roll back
>> etc
>
>> This pattern is directly reflected in the current implementation. See
>> the test suite in libs/rdb/test/test_odbc.cpp.
>>
>> Other vendors may have a different pattern :
>>
>> begin transaction
>> do work
>> commit or roll back
>> begin transaction
>> do work
>> commit or roll back
>
> If you provide an RAII class that does a start/begin/whatever in the ctor, a roll back in the dtor unless cancelled or committed, and provides member functions to commit or cancel on demand, then all back end schemes should be covered.

I agree that a transaction abstraction is nedeed to encapsulates the patterns

transaction() {
  db.set_autocommit(off);
}
~transaction() {
  if not commited db.rollback();

  db.set_autocommit(on);
}

or

transaction() {
  db.begin_transaction(off);
}
~transaction() {
      if not commited db.rollback();

}

Note please the following C++ schema

    for (transaction T; !T.committed() && T.restart(); T.commit()) {
    
    }

That allows us to reiterate as far as the transaction has not successfully commited. The transaction will off course rolled back if not commited on its destructor. This schema has the advantage to preserve the block structure, and the library could provide a macro.

#define BOOST_RDB_ATOMIC(T) for (transaction T; !T.committed() && T.restart(); T.commit())

that allows to have language-like atomic blocks

    BOOST_RDB_ATOMIC(T) {
        // do something atomic
    }

TBoost.STM provides already some of these language-like macros.

The autocommit feature can also be emmulated for backends don't providing it. A autocommit off will create a hidden transaction, which will be make the commit and rollback functions to restart the hiden transaction.
A autocommit on will associate a transaction to the execute function.

If Boost.RDB provide both, free to the user to choose its prefered style.

> The ctor can throw an exception should a particular back end not support transactions.

If the backend do not support a feature it will be preferable to have the information at compile time, isn't it?
 
> Whether a back end supports nested transactions or not puts a wrinkle in the abstraction, of course. I suggest that you model nested transactions and simulate them for back ends that don't support them. In the latter case, the transaction class must use functions in some implementation layer that will track outstanding "nested" transaction objects in order to correctly decide whether to actually roll back when a transaction object's dtor runs or when commit() and roll_back() are called based upon what has already happened to the underlying, tracked state.

I agree again. This seems not too complex to simulate.

Best regards,
Vicente


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk