Expand description
Structs and traits for dealing with distributed transactions.
This crate is an attempt to provide a reasonable rust language binding for XA Distributed Transactions.
So far there is no support for asynchronous operations in resource managers.
Example
Let’s assume we have two (or more) different database connections, most likely to different database installations, and we want to use two-phase-commit to ensure that all our changes to these connections are stored consistently (i.e. all or nothing).
Precondition: both connections (i.e. both drivers) have to be prepared for
working with dist_tx
, and both are not using automatic commit.
let mut conn_a = ...;
let mut conn_b = ...;
First instantiate a SimpleTransactionManager
:
let mut tm = SimpleTransactionManager::new("XA Demo".to_owned());
Then retrieve a ResourceManager
implementation from each connection,
and register it at the transaction manager.
Every registered resource manager is registered with a distinct ID.
In the example below we tell the transaction manager to cleanup eventually
existing open transaction left-overs from previous runs for the two ids.
This makes already clear that the IDs (of type u64
) should be chosen in a way
that minimizes undesired collision probabilities, and maximizes intended “collisions”.
tm.register(conn_a.get_resource_manager(), id_1, true)?;
tm.register(conn_b.get_resource_manager(), id_2, true)?;
Now we start a distributed transaction
tm.start_transaction()?;
and then we’re ready to do all required updates via the two database connections:
...
conn_a.dml(&insert_stmt(1, "foo"))?;
conn_b.dml(&insert_stmt(2, "bar"))?;
...
At this point nothing is committed yet, which we could verify with additional connections
to the two databases that are not registered to tm
.
Finally, when all updates were done successfully, we commit the transaction:
tm.commit_transaction()?;
Now all updates are committed and visible, which we could again verify with additional connections.
Implementation
Database drivers etc, who want to enable their users to take part in distributed
transactions that are managed via dist_tx
, can either implement
rm::ResourceManager
, which is a more
rust-idiomatic interpretation of the XA resource manager,
or they implement rm::CResourceManager
,
which is more C-ish, and wrap it into a rm::CRmWrapper
(which implements rm::ResourceManager
).