[Libpqxx-general] Two phase commit
Maurice Gittens
mainmanmauricio at gmail.com
Sun Aug 16 09:43:52 UTC 2009
Hi Jeroen,
On Sun, Aug 16, 2009 at 9:27 AM, Jeroen T. Vermeulen <jtv at xs4all.nl> wrote:
> Actually the API design is what I haven't done yet. :-)
>
> The most obvious way to go would be to introduce a new transaction method
> "prepare(id)" that brings the transaction into a new state where it's
> detached from the connection and won't accept any further commands except
> commit() or abort(). It would be possible to start new transactions in
> the meantime. Changes made by the transaction would "disappear" again
> between prepare() and commit(). Both commit() and abort() would issue
> different SQL in the prepared state than before it.
>
> On nontransactions, prepare() would be either a no-op or an error. And
> using 2pc with robusttransaction would be redundant, so that leads us to a
> design that offers the prepare() method only in some new transaction type.
> We could even use the transaction's name as its id. The composition of
> transaction classes becomes a bit more complex internally, but the
> external API would be nice and clean.
>
> However this is a pure two-tier design, completely non-transparent to the
> application. To me, two-tier 2pc is an invitation to disaster.
>
> ISTM that ideally a transaction manager would be able to "inject" itself
> into the application, with the application continuing to begin and commit
> transactions as if it were still in direct control.
>
> Maybe that's a pipe dream since the app should know that it's talking to
> multiple resource managers anyway; or maybe complex apps could have
> modules each with their own transactional "contracts" that need to be
> encapsulated transparently.
>
> Here's what I think a transparent 3-tier model would require:
> * A transaction factory to hide the difference in transaction types.
> * Obtaining a transaction id from the transaction manager.
> -> Can we do this in the factory, at the start of the transaction?
> * commit() actually prepares, then waits as the TM does the commit.
>
> Talking to the transaction manager requires configuration, and possibly
> even pluggable protocol support.
>
> Neither of these two models can be cleanly and easily implemented on top
> of the other. The ways I see of doing that would be:
>
> (a) go with the 3-tier model but provide a "fake" transaction manager to
> give the program direct control of its own 2pc, or
>
> (b) go with the 2-tier model except prepare() is still called commit(),
> and expect the application to implement 3-tier or its own cleanup on top.
> Semantics for commit() would be radically unusual, so the transactor
> framework would have to learn about this as well.
>
> Thoughts welcome! Transaction management is a big world that I haven't
> kept much track of. Maybe current standards force once choice or the
> other, though I'm not expecting any final solution to have arrived.
>
I think we would want the API to align well with the mental-model used with
XA compliant TM; keeping things nice and simple in the process.
A suggestion for integration into pqxx follows. (I have no idea if this
suggestion
aligns well with the pqxx design policies).
pqxx::transaction_monitor txmon.
txmon.add_connection("conn1", "a connection string for a postgres db");
// creates new connection
txmon.add_connection("conn2", pqxxConnection1); // use existing
connection
pqxx::transaction<pqxx::read_committed> tx(txmon, "a_tx_id");
// do stuff with the connections;
tx("conn1").exec("select * from pg_class;");
// a managed transaction does not have begin, commit, rollback methods
pqxx::managed_transaction mtx = txmon("conn2");
mtx.exec("select 1")'
// do stuff more stuff
...
tx.prepare();
tx.commit();
To me the above "feels" like pqxx. Would something like the above work?
>
> > So basically, if I use non-transactions for everything, then I can simply
> > issue the
> > SQL statements directly to the underlying connection?
>
> Yes, you can. It's not generally recommended, because the library should
> support the structure you need, but this is really prototyping for the
> right feature.
This is good to know should the need for a work-around arise.
>
>
>
> > Hmm, this sounds tempting, since I can use SQL statements for transaction
> > management and
> > libpqxx functionality for everything else, Right?
>
> Yes. Some more specialized features such as tablestreams may think you're
> not in a real transaction and refuse to work, but basic functionality
> should work. For the more specialized stuff some unrelated errors may be
> misinterpreted as "you can't do this right now, you're not in a
> transaction" by the library.
Ok. Thanks for the info.
Kind regards,
Maurice
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://pgfoundry.org/pipermail/libpqxx-general/attachments/20090816/bd1d174e/attachment.html>
More information about the Libpqxx-general
mailing list