The pattern in brief: | |
Architecture: | see Figure 8.3, “Multiple applications layout” |
Number of Application Programs: | 2 or more |
Number of Resource Managers: | 1 or more for every Application Program |
Number of Branches in the Gloabal Transaction: | 1 for every Application Program |
Concurrency among Application Programs: | yes, subordinate AP prepares the transaction, returns control to superior AP and finally completes commit |
This is a Distributed Transaction Processing pattern introduced by XTA: two or more Application Programs use any set of Resource Manager(s) and perform concurrent operations inside distinct branches of a common XA global transaction. The Resource Manager(s) must support concurrent branches of the same global transaction: this is part of XA standard, but some resource managers might not support it.
The following picture shows an example that can be implemented, for example, using MySQL (or MariaDB) and PostgreSQL.
Figure 8.8. Example of “Multiple Applications, Consecutive Calls/Pseudo Synchronous” with two Application Programs and two Resource Managers
The pattern can not be implemented using the
standard TX Transaction Demarcation interface.
Figure 8.9. Simplified sequence diagram for the “Multiple Applications, Concurrent Branches/Pseudo Synchronous” Pattern
The above figure shows the logic necessary to build this type of applications; it's not a formally correct UML sequence diagram (all the XTA objects are in the same lifeline), but it should be clear enough to understand the proper operations sequence:
Both the Application Programs perform some some initial steps like: opening a native connection to the Resource Manager, creating a Transaction Manager object, a XA Resource Manager object, a Transaction object and finally enlisting and opening the Resource Manager
The first AP, named “superior” using XA terminology, starts the global transaction and possibly updates the state of its Resource Manager
The first AP retrieves the XID associated to the global transaction and starts some sort of “remote procedure call” [50] to invoke the second AP; it must pass the XID and all the application context necessary to operate (this is not relevant to XTA)
The second AP, named “subordinate” using XA terminology, branches the global transaction and possibly updates the state of its Resource Manager
The second AP starts the first phase of the distributed commit specifying “non_block=TRUE” option: this translates in performing “XA prepare” without performing “XA commit”
At the end of the first phase of the distributed commit, the second AP responds to first AP: typically a return code related to commit operation
Since then now, both the APs can run concurrently to complete the distributed commit specifying “non_block=FALSE” option (in the provided example, the first AP performs another update to its Resource Manager before committing)
The last operations are related to clean-up
The dashed red rectangle highlights the XA global transaction.
These are the relevant elements of this pattern:
it's designed for a typical client/server approach with some sort of request-response communication protocol in place
the Application Programs run concurrently, but synchronize themselves by mean of the communication protocol and the LIXA state server: the second phase of the two phase commit protocol can be started only after the completion of the first phase by all the participants
the second Application Program can not terminate immediately after returning the response to the caller: it must perform the second phase of the two phase commit protocol
the first Application Program can perform Resource Manager related operations before and after the call to the second Application Program
the diagram shows an example with two Application Programs, but the pattern can be applied to any number of Application Programs: a subordinate AP can become a superior AP of a called subordinate AP and so on
the diagram shows an example with only one Resource Manager for every Application Program, but there's no restriction on LIXA and XTA side, on the number of Resource Managers used by an Application Program
Not all the Resource Managers have implemented the XA specifications in the same way. This section tracks some limitations that have been reported by the LIXA project.
As described in Oracle's official documentation [51] at paragraph 30-15 “Oracle XA Optimizations”, Oracle JDBC implements additional logic, in comparison with the XA specifications, when two ore more branches of the same global transaction are related to the same Oracle Database instance.
In the event that both AP1 and AP2 use the same Oracle Database
instance strange behaviors could be reported. Furthermore, the second
call to rm.doSomething()
from AP1 could fail as
described in this
case
documented by Red hat, with error
“ORA-02051: another session or branch in same transaction failed or finalized”. A relevant hypotesis described in the case is
“Oracle seems to disallow attempt to execute SQL on a
transaction branch when another branch in the same global transaction
has already prepared its transaction”.
On the other hand, no such limitation has been found in the Oracle OCI interface for C and C++.
The supplied examples (example_xta_macbps01.c
and
example_xta_macbps02.c
) use
PostgreSQL in the role of “Resource Manager 2” and MySQL
(or MariaDB) in the role of “Resource Manager 1”; please
refer to the instructions explained:
in the section called “MySQL Configuration” to set-up a running environment for MySQL server
in the section called “PostgreSQL Configuration” to set-up a running environment for PostgreSQL server
in the section called “Starting the state server (lixad)” to start up the LIXA state server.
Both programs must be used to execute the example:
example_xta_macbps01
in the role of the superior
Application Program (first AP) and
example_xta_macbps02
in the role of the
subordinate Application Program (second AP).
Create a working directory in a place you are comfortable with:
[Shell terminal session] |
tiian@ubuntu1404-64:~$ cd tiian@ubuntu1404-64:~$ mkdir tmp tiian@ubuntu1404-64:~$ cd tmp tiian@ubuntu1404-64:~/tmp$ |
Copy files example_xta_macbps01.c
and
example_xta_macbps02.c
in your working dir:
[Shell terminal session] |
tiian@ubuntu:~/tmp$ cp /opt/lixa/share/doc/lixa-X.Y.Z/examples/xta/example_xta_macbps01.c . tiian@ubuntu:~/tmp$ cp /opt/lixa/share/doc/lixa-X.Y.Z/examples/xta/example_xta_macbps02.c . |
Substitute “X.Y.Z” with the actual version of the software you installed.
Compile and link the C example programs:
[Shell terminal session] |
tiian@ubuntu1404-64:~/tmp$ . /opt/lixa/bin/lixa_env.sh tiian@ubuntu1404-64:~/tmp$ gcc example_xta_macbps01.c $(lixa-config -x -c -f -l -d) $(mysql_config --libs_r) -o example_xta_macbps01 tiian@ubuntu1404-64:~/tmp$ gcc example_xta_macbps02.c $(lixa-config -x -c -f -l -d) -lpq -o example_xta_macbps02 |
If the previous steps worked for you, you should have two executable
files of name example_xta_macbps01
and
example_xta_macbps02
in your current directory:
[Shell terminal session] |
tiian@ubuntu1404-64:~/tmp$ ls -l total 96 -rwxrwxr-x 1 tiian tiian 18499 apr 8 22:08 example_xta_macbps01 -rw-r--r-- 1 tiian tiian 10459 apr 8 11:58 example_xta_macbps01.c -rwxrwxr-x 1 tiian tiian 18319 apr 8 22:08 example_xta_macbps02 -rw-r--r-- 1 tiian tiian 11095 apr 8 11:58 example_xta_macbps02.c |
The example programs accept four arguments:
commit (or rollback): use “1” if you want to perform a global commit or “0” if you want to perform a global rollback
insert (or delete): use “1” if you want to insert rows in databases or “0” if you want to delete rows from databases
name of the FIFO (named pipe) that will be used to send messages from the superior AP to the subordinate AP
name of the FIFO (named pipe) that will be used to return messages from the subordinate AP to the superior AP
Open four terminal sessions: two for the example programs execution,
[Shell terminal session - AP1] |
tiian@ubuntu1404-64:~/tmp$ ls -l example_xta_macbps01 -rwxrwxr-x 1 tiian tiian 18499 apr 8 22:08 example_xta_macbps01 |
[Shell terminal session - AP2] |
tiian@ubuntu1404-64:~/tmp$ ls -l example_xta_macbps02 -rwxrwxr-x 1 tiian tiian 18319 apr 8 22:08 example_xta_macbps02 |
one for MySQL queries,
[Shell terminal session - MySQL] |
tiian@ubuntu1404-64:~$ mysql -h localhost -u lixa lixa Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 36 Server version: 5.5.59-0ubuntu0.14.04.1 (Ubuntu) Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> |
and one for PostgreSQL queries
[Shell terminal session - PostgreSQL] |
tiian@ubuntu1404-64:~$ psql testdb psql (9.3.22) Type "help" for help. testdb=> |
Set LIXA_PROFILE
environment variable to
XTA_DYN
,
a profile without static Resource Managers defined in
lixac_conf.xml
:
[Shell terminal session - AP1] |
tiian@ubuntu1404-64:~/tmp$ export LIXA_PROFILE=XTA_DYN tiian@ubuntu1404-64:~/tmp$ echo $LIXA_PROFILE XTA_DYN |
[Shell terminal session - AP2] |
tiian@ubuntu1404-64:~/tmp$ export LIXA_PROFILE=XTA_DYN tiian@ubuntu1404-64:~/tmp$ echo $LIXA_PROFILE XTA_DYN |
create two named pipes (FIFO) to support communication between superior and subordinate Application Programs
[Shell terminal session - AP1] |
tiian@ubuntu1404-64:~/tmp$ mkfifo sup2sub tiian@ubuntu1404-64:~/tmp$ mkfifo sub2sup tiian@ubuntu1404-64:~/tmp$ ls -l su* prw-rw-r-- 1 tiian tiian 0 apr 8 22:22 sub2sup prw-rw-r-- 1 tiian tiian 0 apr 8 22:22 sup2sub |
execute both the example programs to insert rows in tables and commit:
[Shell terminal session - AP1] |
tiian@ubuntu1404-64:~/tmp$ ./example_xta_macbps01 1 1 sup2sub sub2sup MySQL, executing >INSERT INTO authors VALUES(1919, 'Levi', 'Primo')< Superior AP has sent XID '1279875137.b6df6743cbf54cb8b8323ca5ab771e6e.e107cfeee0661d23da9322f1ee73faba' to subordinate AP Superior AP has received 'PREPARED_for_COMMIT' reply from subordinate AP MySQL, executing >INSERT INTO authors VALUES(1898, 'Remarque', 'Erich Maria')< tiian@ubuntu1404-64:~/tmp$ |
[Shell terminal session - AP2] |
tiian@ubuntu1404-64:~/tmp$ ./example_xta_macbps02 1 1 sup2sub sub2sup Subordinate AP has received XID '1279875137.b6df6743cbf54cb8b8323ca5ab771e6e.e107cfeee0661d23da9322f1ee73faba' from superior AP Subordinate AP has created a branch with XID '1279875137.b6df6743cbf54cb8b8323ca5ab771e6e.e107cfeee0661d23af7f136da1b84c3b' PostgreSQL, executing >INSERT INTO authors VALUES(1921, 'Rigoni Stern', 'Mario')< Subordinate AP has returned 'PREPARED_for_COMMIT' to superior AP tiian@ubuntu1404-64:~/tmp$ |
The first (superior) Application Program suspends and waits the return value from the second (subordinate) Application Program.
The XID generated by the subordinate AP differs from the XID generated by the superior AP in the last 16 hexadecimal symbols of the “branch qualifier”; the first 16 hexadecimal symbols are the same: this is not required by XA specification but can be useful for troubleshooting purposes.
Check MySQL table content:
[Shell terminal session - MySQL] |
mysql> select * from authors; +------+-----------+-------------+ | id | last_name | first_name | +------+-----------+-------------+ | 1898 | Remarque | Erich Maria | | 1919 | Levi | Primo | +------+-----------+-------------+ 2 rows in set (0.00 sec) mysql> |
check PostgreSQL table content:
[Shell terminal session - PostgreSQL] |
testdb=> select * from authors; id | last_name | first_name ------+--------------+------------ 1921 | Rigoni Stern | Mario (1 row) testdb=> |
delete rows from tables, but rollback:
[Shell terminal session - AP1] |
tiian@ubuntu1404-64:~/tmp$ ./example_xta_macbps01 0 0 sup2sub sub2sup MySQL, executing >DELETE FROM authors WHERE id=1919< Superior AP has sent XID '1279875137.1911a9c72cec45eea47ffc74cf95e000.e107cfeee0661d23da9322f1ee73faba' to subordinate AP Superior AP has received 'ROLLBACK' reply from subordinate AP MySQL, executing >DELETE FROM authors WHERE id=1898< tiian@ubuntu1404-64:~/tmp$ |
[Shell terminal session - AP2] |
tiian@ubuntu1404-64:~/tmp$ ./example_xta_macbps02 0 0 sup2sub sub2sup Subordinate AP has received XID '1279875137.1911a9c72cec45eea47ffc74cf95e000.e107cfeee0661d23da9322f1ee73faba' from superior AP Subordinate AP has created a branch with XID '1279875137.1911a9c72cec45eea47ffc74cf95e000.e107cfeee0661d233a125b14214944da' PostgreSQL, executing >DELETE FROM authors WHERE id=1921< Subordinate AP has returned 'ROLLBACK' to superior AP tiian@ubuntu1404-64:~/tmp$ |
check MySQL table content:
[Shell terminal session - MySQL] |
mysql> select * from authors; +------+-----------+-------------+ | id | last_name | first_name | +------+-----------+-------------+ | 1898 | Remarque | Erich Maria | | 1919 | Levi | Primo | +------+-----------+-------------+ 2 rows in set (0.00 sec) mysql> |
check PostgreSQL table content:
[Shell terminal session - PostgreSQL] |
testdb=> select * from authors; id | last_name | first_name ------+--------------+------------ 1921 | Rigoni Stern | Mario (1 row) testdb=> |
delete rows and commit:
[Shell terminal session - AP1] |
tiian@ubuntu1404-64:~/tmp$ ./example_xta_macbps01 1 0 sup2sub sub2sup MySQL, executing >DELETE FROM authors WHERE id=1919< Superior AP has sent XID '1279875137.c862b6aa72784c808e6c59388e4263a9.e107cfeee0661d23da9322f1ee73faba' to subordinate AP Superior AP has received 'PREPARED_for_COMMIT' reply from subordinate AP MySQL, executing >DELETE FROM authors WHERE id=1898< tiian@ubuntu1404-64:~/tmp$ |
[Shell terminal session - AP2] |
tiian@ubuntu1404-64:~/tmp$ ./example_xta_macbps02 1 0 sup2sub sub2sup Subordinate AP has received XID '1279875137.c862b6aa72784c808e6c59388e4263a9.e107cfeee0661d23da9322f1ee73faba' from superior AP Subordinate AP has created a branch with XID '1279875137.c862b6aa72784c808e6c59388e4263a9.e107cfeee0661d234acf9ddb30da46f9' PostgreSQL, executing >DELETE FROM authors WHERE id=1921< Subordinate AP has returned 'PREPARED_for_COMMIT' to superior AP tiian@ubuntu1404-64:~/tmp$ |
check MySQL table content:
[Shell terminal session - MySQL] |
mysql> select * from authors; Empty set (0.00 sec) mysql> |
check PostgreSQL table content:
[Shell terminal session - PostgreSQL] |
testdb=> select * from authors; id | last_name | first_name ------+--------------+------------ (0 rows) testdb=> |
Source code for programs example_xta_macbps01.c
and example_xta_macbps02.c
are
installed in directory
/opt/lixa/share/doc/lixa-X.Y.Z/examples/xta
and
are available on GitHub. Source code is fully
commented for readability.
The supplied examples (example_xta_macbps11.cpp
and example_xta_macbps12.cpp
) use
PostgreSQL in the role of “Resource Manager 2” and MySQL
(or MariaDB) in the role of “Resource Manager 1”; please
refer to the instructions explained:
in the section called “MySQL Configuration” to set-up a running environment for MySQL server
in the section called “PostgreSQL Configuration” to set-up a running environment for PostgreSQL server
in the section called “Starting the state server (lixad)” to start up the LIXA state server.
Both programs must be used to execute the example:
example_xta_macbps11
in the role of the superior
Application Program (first AP) and
example_xta_macbps12
in the role of the
subordinate Application Program (second AP).
Create a working directory in a place you are comfortable with:
[Shell terminal session] |
tiian@ubuntu1404-64:~$ cd tiian@ubuntu1404-64:~$ mkdir tmp tiian@ubuntu1404-64:~$ cd tmp tiian@ubuntu1404-64:~/tmp$ |
Copy files example_xta_macbps11.cpp
and
example_xta_macbps12.cpp
in your working dir:
[Shell terminal session] |
tiian@ubuntu:~/tmp$ cp /opt/lixa/share/doc/lixa-X.Y.Z/examples/xta/cpp/example_xta_macbps11.cpp . tiian@ubuntu:~/tmp$ cp /opt/lixa/share/doc/lixa-X.Y.Z/examples/xta/cpp/example_xta_macbps12.cpp . |
Substitute “X.Y.Z” with the actual version of the software you installed.
Compile and link the C++ example programs:
[Shell terminal session] |
tiian@ubuntu1404-64:~/tmp$ . /opt/lixa/bin/lixa_env.sh tiian@ubuntu1404-64:~/tmp$ g++ example_xta_macbps11.cpp $(lixa-config -c -f -l -d --xta --language-cpp) $(mysql_config --libs_r) -o example_xta_macbps11 tiian@ubuntu1404-64:~/tmp$ g++ example_xta_macbps12.cpp $(lixa-config -c -f -l -d --xta --language-cpp) -lpq -o example_xta_macbps12 |
If the previous steps worked for you, you should have two executable
files of name example_xta_macbps11
and
example_xta_macbps12
in your current directory:
[Shell terminal session] |
tiian@ubuntu1404-64:~/tmp$ ls -l total 80 -rwxrwxr-x 1 tiian tiian 26419 ago 26 21:56 example_xta_macbps11 -rw-r--r-- 1 tiian tiian 8779 ago 26 21:54 example_xta_macbps11.cpp -rwxrwxr-x 1 tiian tiian 26399 ago 26 21:56 example_xta_macbps12 -rw-r--r-- 1 tiian tiian 10028 ago 26 21:54 example_xta_macbps12.cpp |
The example programs accept four arguments:
commit (or rollback): use “1” if you want to perform a global commit or “0” if you want to perform a global rollback
insert (or delete): use “1” if you want to insert rows in databases or “0” if you want to delete rows from databases
name of the FIFO (named pipe) that will be used to send messages from the superior AP to the subordinate AP
name of the FIFO (named pipe) that will be used to return messages from the subordinate AP to the superior AP
Open four terminal sessions: two for the example programs execution,
[Shell terminal session - AP1] |
tiian@ubuntu1404-64:~/tmp$ ls -l example_xta_macbps11 -rwxrwxr-x 1 tiian tiian 18499 apr 8 22:08 example_xta_macbps11 |
[Shell terminal session - AP2] |
tiian@ubuntu1404-64:~/tmp$ ls -l example_xta_macbps12 -rwxrwxr-x 1 tiian tiian 18319 apr 8 22:08 example_xta_macbps12 |
one for MySQL queries,
[Shell terminal session - MySQL] |
tiian@ubuntu1404-64:~$ mysql -h localhost -u lixa lixa Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 36 Server version: 5.5.61-0ubuntu0.14.04.1 (Ubuntu) Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> |
and one for PostgreSQL queries
[Shell terminal session - PostgreSQL] |
tiian@ubuntu1404-64:~$ psql testdb psql (9.3.24) Type "help" for help. testdb=> |
Set LIXA_PROFILE
environment variable to
XTA_DYN
,
a profile without static Resource Managers defined in
lixac_conf.xml
:
[Shell terminal session - AP1] |
tiian@ubuntu1404-64:~/tmp$ export LIXA_PROFILE=XTA_DYN tiian@ubuntu1404-64:~/tmp$ echo $LIXA_PROFILE XTA_DYN |
[Shell terminal session - AP2] |
tiian@ubuntu1404-64:~/tmp$ export LIXA_PROFILE=XTA_DYN tiian@ubuntu1404-64:~/tmp$ echo $LIXA_PROFILE XTA_DYN |
create two named pipes (FIFO) to support communication between superior and subordinate Application Programs
[Shell terminal session - AP1] |
tiian@ubuntu1404-64:~/tmp$ mkfifo sup2sub tiian@ubuntu1404-64:~/tmp$ mkfifo sub2sup tiian@ubuntu1404-64:~/tmp$ ls -l su* prw-rw-r-- 1 tiian tiian 0 ago 26 22:01 sub2sup prw-rw-r-- 1 tiian tiian 0 ago 26 22:01 sup2sub |
execute both the example programs to insert rows in tables and commit:
[Shell terminal session - AP1] |
tiian@ubuntu1404-64:~/tmp$ ./example_xta_macbps11 1 1 sup2sub sub2sup MySQL, executing >INSERT INTO authors VALUES(1919, 'Levi', 'Primo')< Superior AP has sent XID '1279875137.a65b66b6b0874a948f8f09b7a23dd471.e107cfeee0661d23da9322f1ee73faba' to subordinate AP Superior AP has received 'PREPARED_for_COMMIT' reply from subordinate AP MySQL, executing >INSERT INTO authors VALUES(1898, 'Remarque', 'Erich Maria')< tiian@ubuntu1404-64:~/tmp$ |
[Shell terminal session - AP2] |
tiian@ubuntu1404-64:~/tmp$ ./example_xta_macbps12 1 1 sup2sub sub2sup Subordinate AP has received XID '1279875137.a65b66b6b0874a948f8f09b7a23dd471.e107cfeee0661d23da9322f1ee73faba' from superior AP Subordinate AP has created a branch with XID '1279875137.a65b66b6b0874a948f8f09b7a23dd471.e107cfeee0661d235888e12f34d54013' PostgreSQL, executing >INSERT INTO authors VALUES(1921, 'Rigoni Stern', 'Mario')< Subordinate AP has returned 'PREPARED_for_COMMIT' to superior AP tiian@ubuntu1404-64:~/tmp$ |
The first (superior) Application Program suspends and waits the return value from the second (subordinate) Application Program.
The XID generated by the subordinate AP differs from the XID generated by the superior AP in the last 16 hexadecimal symbols of the “branch qualifier”; the first 16 hexadecimal symbols are the same: this is not required by XA specification but can be useful for troubleshooting purposes.
Check MySQL table content:
[Shell terminal session - MySQL] |
mysql> select * from authors; +------+-----------+-------------+ | id | last_name | first_name | +------+-----------+-------------+ | 1898 | Remarque | Erich Maria | | 1919 | Levi | Primo | +------+-----------+-------------+ 2 rows in set (0.00 sec) mysql> |
check PostgreSQL table content:
[Shell terminal session - PostgreSQL] |
testdb=> select * from authors; id | last_name | first_name ------+--------------+------------ 1921 | Rigoni Stern | Mario (1 row) testdb=> |
delete rows from tables, but rollback:
[Shell terminal session - AP1] |
tiian@ubuntu1404-64:~/tmp$ ./example_xta_macbps11 0 0 sup2sub sub2sup MySQL, executing >DELETE FROM authors WHERE id=1919< Superior AP has sent XID '1279875137.b154aa98393d44098c8a20ed2ba488cf.e107cfeee0661d23da9322f1ee73faba' to subordinate AP Superior AP has received 'ROLLBACK' reply from subordinate AP MySQL, executing >DELETE FROM authors WHERE id=1898< tiian@ubuntu1404-64:~/tmp$ |
[Shell terminal session - AP2] |
tiian@ubuntu1404-64:~/tmp$ ./example_xta_macbps12 0 0 sup2sub sub2sup Subordinate AP has received XID '1279875137.b154aa98393d44098c8a20ed2ba488cf.e107cfeee0661d23da9322f1ee73faba' from superior AP Subordinate AP has created a branch with XID '1279875137.b154aa98393d44098c8a20ed2ba488cf.e107cfeee0661d237add9066cfc34a81' PostgreSQL, executing >DELETE FROM authors WHERE id=1921< Subordinate AP has returned 'ROLLBACK' to superior AP tiian@ubuntu1404-64:~/tmp$ |
check MySQL table content:
[Shell terminal session - MySQL] |
mysql> select * from authors; +------+-----------+-------------+ | id | last_name | first_name | +------+-----------+-------------+ | 1898 | Remarque | Erich Maria | | 1919 | Levi | Primo | +------+-----------+-------------+ 2 rows in set (0.00 sec) mysql> |
check PostgreSQL table content:
[Shell terminal session - PostgreSQL] |
testdb=> select * from authors; id | last_name | first_name ------+--------------+------------ 1921 | Rigoni Stern | Mario (1 row) testdb=> |
delete rows and commit:
[Shell terminal session - AP1] |
tiian@ubuntu1404-64:~/tmp$ ./example_xta_macbps11 1 0 sup2sub sub2sup MySQL, executing >DELETE FROM authors WHERE id=1919< Superior AP has sent XID '1279875137.06db3e25e74a4a03bdf7ef4924409255.e107cfeee0661d23da9322f1ee73faba' to subordinate AP Superior AP has received 'PREPARED_for_COMMIT' reply from subordinate AP MySQL, executing >DELETE FROM authors WHERE id=1898< tiian@ubuntu1404-64:~/tmp$ |
[Shell terminal session - AP2] |
tiian@ubuntu1404-64:~/tmp$ ./example_xta_macbps12 1 0 sup2sub sub2sup Subordinate AP has received XID '1279875137.06db3e25e74a4a03bdf7ef4924409255.e107cfeee0661d23da9322f1ee73faba' from superior AP Subordinate AP has created a branch with XID '1279875137.06db3e25e74a4a03bdf7ef4924409255.e107cfeee0661d23cc258059f852467e' PostgreSQL, executing >DELETE FROM authors WHERE id=1921< Subordinate AP has returned 'PREPARED_for_COMMIT' to superior AP tiian@ubuntu1404-64:~/tmp$ |
check MySQL table content:
[Shell terminal session - MySQL] |
mysql> select * from authors; Empty set (0.00 sec) mysql> |
check PostgreSQL table content:
[Shell terminal session - PostgreSQL] |
testdb=> select * from authors; id | last_name | first_name ------+--------------+------------ (0 rows) testdb=> |
Source code for programs example_xta_macbps11.cpp
and example_xta_macbps12.cpp
are
installed in directory
/opt/lixa/share/doc/lixa-X.Y.Z/examples/xta/cpp
and
are available on GitHub. Source code is fully
commented for readability.
The supplied examples (ExampleXtaMACBPS31.java
and ExampleXtaMACBPS32.java
) use
PostgreSQL in the role of “Resource Manager 2” and MySQL
(or MariaDB) in the role of “Resource Manager 1”; please
refer to the instructions explained:
in the section called “MySQL Configuration” to set-up a running environment for MySQL server
in the section called “PostgreSQL Configuration” to set-up a running environment for PostgreSQL server
in the section called “Starting the state server (lixad)” to start up the LIXA state server.
Both programs must be used to execute the example:
ExampleXtaMACBPS31.class
in the role of the
superior Application Program (first AP) and
ExampleXtaMACBPS31.class
in the role of the
subordinate Application Program (second AP).
Create a working directory in a place you are comfortable with:
[Shell terminal session] |
tiian@ubuntu1404-64:~$ cd tiian@ubuntu1404-64:~$ mkdir tmp tiian@ubuntu1404-64:~$ cd tmp tiian@ubuntu1404-64:~/tmp$ |
Copy files ExampleXtaMACBPS31.java
and
ExampleXtaMACBPS32.java
in your working dir:
[Shell terminal session] |
tiian@ubuntu:~/tmp$ cp /opt/lixa/share/doc/lixa-X.Y.Z/examples/xta/java/ExampleXtaMACBPS31.java . tiian@ubuntu:~/tmp$ cp /opt/lixa/share/doc/lixa-X.Y.Z/examples/xta/java/ExampleXtaMACBPS32.java . |
Substitute “X.Y.Z” with the actual version of the software you installed.
Use the proper paths for MySQL and PostgreSQL jars, then compile the Java example programs with something like:
[Shell terminal session] |
tiian@ubuntu1404-64:~/tmp$ javac -cp /opt/lixa/share/lixa/java/xta.jar:/usr/share/java/mysql.jar ExampleXtaMACBPS31.java tiian@ubuntu1404-64:~/tmp$ javac -cp /opt/lixa/share/lixa/java/xta.jar:/opt/postgresql/postgresql.jar ExampleXtaMACBPS32.java |
If the previous steps worked for you, you should have two class
files of name ExampleXtaMACBPS31.class
and
ExampleXtaMACBPS32.class
in your current
directory:
[Shell terminal session] |
tiian@ubuntu1404-64:~/tmp$ ls -l total 40 -rw-rw-r-- 1 tiian tiian 4360 gen 16 21:50 ExampleXtaMACBPS31.class -rw-r--r-- 1 tiian tiian 9006 gen 16 21:50 ExampleXtaMACBPS31.java -rw-rw-r-- 1 tiian tiian 4436 gen 16 21:51 ExampleXtaMACBPS32.class -rw-r--r-- 1 tiian tiian 10425 gen 16 21:47 ExampleXtaMACBPS32.java |
The example programs accept four arguments:
commit (or rollback): use “1” if you want to perform a global commit or “0” if you want to perform a global rollback
insert (or delete): use “1” if you want to insert rows in databases or “0” if you want to delete rows from databases
name of the FIFO (named pipe) that will be used to send messages from the superior AP to the subordinate AP
name of the FIFO (named pipe) that will be used to return messages from the subordinate AP to the superior AP
Open four terminal sessions: two for the example programs execution,
[Shell terminal session - AP1] |
tiian@ubuntu1404-64:~/tmp$ ls -l ExampleXtaMACBPS31.class -rw-rw-r-- 1 tiian tiian 4360 gen 16 21:50 ExampleXtaMACBPS31.class |
[Shell terminal session - AP2] |
tiian@ubuntu1404-64:~/tmp$ ls -l ExampleXtaMACBPS32.class -rw-rw-r-- 1 tiian tiian 4436 gen 16 21:51 ExampleXtaMACBPS32.class |
one for MySQL queries,
[Shell terminal session - MySQL] |
tiian@ubuntu1404-64:~$ mysql -h localhost -u lixa lixa Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 36 Server version: 5.5.62-0ubuntu0.14.04.1 (Ubuntu) Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> |
and one for PostgreSQL queries
[Shell terminal session - PostgreSQL] |
tiian@ubuntu1404-64:~$ psql testdb psql (9.3.24) Type "help" for help. testdb=> |
Set LIXA_PROFILE
environment variable to
XTA_DYN
,
a profile without static Resource Managers defined in
lixac_conf.xml
:
[Shell terminal session - AP1] |
tiian@ubuntu1404-64:~/tmp$ export LIXA_PROFILE=XTA_DYN tiian@ubuntu1404-64:~/tmp$ echo $LIXA_PROFILE XTA_DYN |
[Shell terminal session - AP2] |
tiian@ubuntu1404-64:~/tmp$ export LIXA_PROFILE=XTA_DYN tiian@ubuntu1404-64:~/tmp$ echo $LIXA_PROFILE XTA_DYN |
create two named pipes (FIFO) to support communication between superior and subordinate Application Programs
[Shell terminal session - AP1] |
tiian@ubuntu1404-64:~/tmp$ mkfifo sup2sub tiian@ubuntu1404-64:~/tmp$ mkfifo sub2sup tiian@ubuntu1404-64:~/tmp$ ls -l su* prw-rw-r-- 1 tiian tiian 0 gen 16 21:58 sub2sup prw-rw-r-- 1 tiian tiian 0 gen 16 21:57 sup2sub |
execute both the example programs to insert rows in tables and commit:
[Shell terminal session - AP1] |
tiian@ubuntu1404-64:~/tmp$ java -Djava.library.path=/opt/lixa/lib -cp /opt/lixa/share/lixa/java/xta.jar:/usr/share/java/mysql.jar:. ExampleXtaMACBPS31 1 1 sup2sub sub2sup MySQL, executing >INSERT INTO authors VALUES(1919, 'Levi', 'Primo')< Superior AP has sent XID '1279875137.7f8a0b782a764545934d3052c38c89c0.cd976821ac38611801b6e378a35a3c7a' to subordinate AP Superior AP has received 'PREPARED_for_COMMIT' reply from subordinate AP MySQL, executing >INSERT INTO authors VALUES(1898, 'Remarque', 'Erich Maria')< tiian@ubuntu1404-64:~/tmp$ |
[Shell terminal session - AP2] |
tiian@ubuntu1404-64:~/tmp$ java -Djava.library.path=/opt/lixa/lib -cp /opt/lixa/share/lixa/java/xta.jar:/opt/postgresql/postgresql.jar:. ExampleXtaMACBPS32 1 1 sup2sub sub2sup Subordinate AP has received XID '1279875137.7f8a0b782a764545934d3052c38c89c0.cd976821ac38611801b6e378a35a3c7a' from superior AP Subordinate AP has created a branch with XID '1279875137.7f8a0b782a764545934d3052c38c89c0.cd976821ac386118e3c0422932534d2e' PostgreSQL, executing >INSERT INTO authors VALUES(1921, 'Rigoni Stern', 'Mario')< Subordinate AP has returned 'PREPARED_for_COMMIT' to superior AP tiian@ubuntu1404-64:~/tmp$ |
The first (superior) Application Program suspends and waits the return value from the second (subordinate) Application Program.
The XID generated by the subordinate AP differs from the XID generated by the superior AP in the last 16 hexadecimal symbols of the “branch qualifier”; the first 16 hexadecimal symbols are the same: this is not required by XA specification but can be useful for troubleshooting purposes.
Check MySQL table content:
[Shell terminal session - MySQL] |
mysql> select * from authors; +------+-----------+-------------+ | id | last_name | first_name | +------+-----------+-------------+ | 1898 | Remarque | Erich Maria | | 1919 | Levi | Primo | +------+-----------+-------------+ 2 rows in set (0.00 sec) mysql> |
check PostgreSQL table content:
[Shell terminal session - PostgreSQL] |
testdb=> select * from authors; id | last_name | first_name ------+--------------+------------ 1921 | Rigoni Stern | Mario (1 row) testdb=> |
delete rows from tables, but rollback:
[Shell terminal session - AP1] |
tiian@ubuntu1404-64:~/tmp$ java -Djava.library.path=/opt/lixa/lib -cp /opt/lixa/share/lixa/java/xta.jar:/usr/share/java/mysql.jar:. ExampleXtaMACBPS31 0 0 sup2sub sub2sup MySQL, executing >DELETE FROM authors WHERE id=1919< Superior AP has sent XID '1279875137.76c07087a5d1433c9c985c8976800060.cd976821ac38611801b6e378a35a3c7a' to subordinate AP Superior AP has received 'ROLLBACK' reply from subordinate AP MySQL, executing >DELETE FROM authors WHERE id=1898< tiian@ubuntu1404-64:~/tmp$ |
[Shell terminal session - AP2] |
tiian@ubuntu1404-64:~/tmp$ java -Djava.library.path=/opt/lixa/lib -cp /opt/lixa/share/lixa/java/xta.jar:/opt/postgresql/postgresql.jar:. ExampleXtaMACBPS32 0 0 sup2sub sub2sup Subordinate AP has received XID '1279875137.76c07087a5d1433c9c985c8976800060.cd976821ac38611801b6e378a35a3c7a' from superior AP Subordinate AP has created a branch with XID '1279875137.76c07087a5d1433c9c985c8976800060.cd976821ac386118d8720d87412a4927' PostgreSQL, executing >DELETE FROM authors WHERE id=1921< Subordinate AP has returned 'ROLLBACK' to superior AP tiian@ubuntu1404-64:~/tmp$ |
check MySQL table content:
[Shell terminal session - MySQL] |
mysql> select * from authors; +------+-----------+-------------+ | id | last_name | first_name | +------+-----------+-------------+ | 1898 | Remarque | Erich Maria | | 1919 | Levi | Primo | +------+-----------+-------------+ 2 rows in set (0.00 sec) mysql> |
check PostgreSQL table content:
[Shell terminal session - PostgreSQL] |
testdb=> select * from authors; id | last_name | first_name ------+--------------+------------ 1921 | Rigoni Stern | Mario (1 row) testdb=> |
delete rows and commit:
[Shell terminal session - AP1] |
tiian@ubuntu1404-64:~/tmp$ java -Djava.library.path=/opt/lixa/lib -cp /opt/lixa/share/lixa/java/xta.jar:/usr/share/java/mysql.jar:. ExampleXtaMACBPS31 1 0 sup2sub sub2sup MySQL, executing >DELETE FROM authors WHERE id=1919< Superior AP has sent XID '1279875137.a31bf2c7780345f98112c613685780bd.cd976821ac38611801b6e378a35a3c7a' to subordinate AP Superior AP has received 'PREPARED_for_COMMIT' reply from subordinate AP MySQL, executing >DELETE FROM authors WHERE id=1898< tiian@ubuntu1404-64:~/tmp$ |
[Shell terminal session - AP2] |
tiian@ubuntu1404-64:~/tmp$ java -Djava.library.path=/opt/lixa/lib -cp /opt/lixa/share/lixa/java/xta.jar:/opt/postgresql/postgresql.jar:. ExampleXtaMACBPS32 1 0 sup2sub sub2sup Subordinate AP has received XID '1279875137.a31bf2c7780345f98112c613685780bd.cd976821ac38611801b6e378a35a3c7a' from superior AP Subordinate AP has created a branch with XID '1279875137.a31bf2c7780345f98112c613685780bd.cd976821ac38611837020c0b51914e74' PostgreSQL, executing >DELETE FROM authors WHERE id=1921< Subordinate AP has returned 'PREPARED_for_COMMIT' to superior AP tiian@ubuntu1404-64:~/tmp$ |
check MySQL table content:
[Shell terminal session - MySQL] |
mysql> select * from authors; Empty set (0.00 sec) mysql> |
check PostgreSQL table content:
[Shell terminal session - PostgreSQL] |
testdb=> select * from authors; id | last_name | first_name ------+--------------+------------ (0 rows) testdb=> |
Source code for programs
ExampleXtaMACBPS31.java
and ExampleXtaMACBPS32.java
are
installed in directory
/opt/lixa/share/doc/lixa-X.Y.Z/examples/xta/java
and are available on GitHub. Source code is fully
commented for readability.
The supplied examples (example_xta_macbps21.py
and example_xta_macbps22.py
) use
PostgreSQL in the role of “Resource Manager 2” and MySQL
(or MariaDB) in the role of “Resource Manager 1”; please
refer to the instructions explained:
in the section called “XTA Technology Matrix” to build and install the Python database drivers that can be used with XTA
in the section called “MySQL Configuration” to set-up a running environment for MySQL server
in the section called “PostgreSQL Configuration” to set-up a running environment for PostgreSQL server
in the section called “Starting the state server (lixad)” to start up the LIXA state server.
Both programs must be used to execute the example:
example_xta_macbps21.py
in the role of the
superior Application Program (first AP) and
example_xta_macbps22.py
in the role of the
subordinate Application Program (second AP).
Python 2 and Python 3 can be used even mixing them: one for the first
AP and one for the second AP.
Create a working directory in a place you are comfortable with:
[Shell terminal session] |
tiian@ubuntu1404-64:~$ cd tiian@ubuntu1404-64:~$ mkdir tmp tiian@ubuntu1404-64:~$ cd tmp tiian@ubuntu1404-64:~/tmp$ |
Copy files example_xta_macbps21.py
and
example_xta_macbps22.py
in your working dir:
[Shell terminal session] |
tiian@ubuntu:~/tmp$ cp /opt/lixa/share/doc/lixa-X.Y.Z/examples/xta/python/example_xta_macbps21.py . tiian@ubuntu:~/tmp$ cp /opt/lixa/share/doc/lixa-X.Y.Z/examples/xta/python/example_xta_macbps22.py . |
Substitute “X.Y.Z” with the actual version of the software you installed.
The example programs accept four arguments:
commit (or rollback): use “1” if you want to perform a global commit or “0” if you want to perform a global rollback
insert (or delete): use “1” if you want to insert rows in databases or “0” if you want to delete rows from databases
name of the FIFO (named pipe) that will be used to send messages from the superior AP to the subordinate AP
name of the FIFO (named pipe) that will be used to return messages from the subordinate AP to the superior AP
Open four terminal sessions: two for the example programs execution,
[Shell terminal session - AP1] |
tiian@ubuntu1404-64:~/tmp$ ls -l example_xta_macbps21.py -rw-r--r-- 1 tiian tiian 4701 ott 15 22:28 example_xta_macbps21.py |
[Shell terminal session - AP2] |
tiian@ubuntu1404-64:~/tmp$ ls -l example_xta_macbps22.py -rw-r--r-- 1 tiian tiian 5266 ott 15 22:28 example_xta_macbps22.py |
one for MySQL queries,
[Shell terminal session - MySQL] |
tiian@ubuntu1404-64:~$ mysql -h localhost -u lixa lixa Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 36 Server version: 5.5.61-0ubuntu0.14.04.1 (Ubuntu) Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> |
and one for PostgreSQL queries
[Shell terminal session - PostgreSQL] |
tiian@ubuntu1404-64:~$ psql testdb psql (9.3.24) Type "help" for help. testdb=> |
Set LIXA_PROFILE
environment variable to
XTA_DYN
,
a profile without static Resource Managers defined in
lixac_conf.xml
:
[Shell terminal session - AP1] |
tiian@ubuntu1404-64:~/tmp$ export LIXA_PROFILE=XTA_DYN tiian@ubuntu1404-64:~/tmp$ echo $LIXA_PROFILE XTA_DYN |
[Shell terminal session - AP2] |
tiian@ubuntu1404-64:~/tmp$ export LIXA_PROFILE=XTA_DYN tiian@ubuntu1404-64:~/tmp$ echo $LIXA_PROFILE XTA_DYN |
create two named pipes (FIFO) to support communication between superior and subordinate Application Programs
[Shell terminal session - AP1] |
tiian@ubuntu1404-64:~/tmp$ mkfifo sup2sub tiian@ubuntu1404-64:~/tmp$ mkfifo sub2sup tiian@ubuntu1404-64:~/tmp$ ls -l su* prw-rw-r-- 1 tiian tiian 0 ott 15 22:35 sub2sup prw-rw-r-- 1 tiian tiian 0 ott 15 22:35 sup2sub |
execute both the example programs to insert rows in tables and commit:
[Shell terminal session - AP1] |
tiian@ubuntu1404-64:~/tmp$ python example_xta_macbps21.py 1 1 sup2sub sub2sup MySQL, executing >INSERT INTO authors VALUES(1919, 'Levi', 'Primo')< Superior AP has sent XID '1279875137.9d22af42e46f4111b23ba3630479c6b9.e107cfeee0661d23da9322f1ee73faba' to subordinate AP Superior AP has received 'PREPARED_for_COMMIT' reply from subordinate AP MySQL, executing >INSERT INTO authors VALUES(1898, 'Remarque', 'Erich Maria')< Superior AP has committed its branch tiian@ubuntu1404-64:~/tmp$ |
[Shell terminal session - AP2] |
tiian@ubuntu1404-64:~/tmp$ python example_xta_macbps22.py 1 1 sup2sub sub2sup Subordinate AP has received XID '1279875137.9d22af42e46f4111b23ba3630479c6b9.e107cfeee0661d23da9322f1ee73faba' from superior AP Subordinate AP has created a branch with XID '1279875137.9d22af42e46f4111b23ba3630479c6b9.e107cfeee0661d23feeb9fdbaca14974' PostgreSQL, executing >INSERT INTO authors VALUES(1921, 'Rigoni Stern', 'Mario')< Subordinate AP has returned 'PREPARED_for_COMMIT' to superior AP tiian@ubuntu1404-64:~/tmp$ |
The first (superior) Application Program suspends and waits the return value from the second (subordinate) Application Program.
The XID generated by the subordinate AP differs from the XID generated by the superior AP in the last 16 hexadecimal symbols of the “branch qualifier”; the first 16 hexadecimal symbols are the same: this is not required by XA specification but can be useful for troubleshooting purposes.
Check MySQL table content:
[Shell terminal session - MySQL] |
mysql> select * from authors; +------+-----------+-------------+ | id | last_name | first_name | +------+-----------+-------------+ | 1898 | Remarque | Erich Maria | | 1919 | Levi | Primo | +------+-----------+-------------+ 2 rows in set (0.00 sec) mysql> |
check PostgreSQL table content:
[Shell terminal session - PostgreSQL] |
testdb=> select * from authors; id | last_name | first_name ------+--------------+------------ 1921 | Rigoni Stern | Mario (1 row) testdb=> |
delete rows from tables, but rollback:
[Shell terminal session - AP1] |
tiian@ubuntu1404-64:~/tmp$ python example_xta_macbps21.py 0 0 sup2sub sub2sup MySQL, executing >DELETE FROM authors WHERE id=1919< Superior AP has sent XID '1279875137.84ab3fdb762742a096a8181043938232.e107cfeee0661d23da9322f1ee73faba' to subordinate AP Superior AP has received 'ROLLBACK' reply from subordinate AP MySQL, executing >DELETE FROM authors WHERE id=1898< Superior AP has rolled back its branch tiian@ubuntu1404-64:~/tmp$ |
[Shell terminal session - AP2] |
tiian@ubuntu1404-64:~/tmp$ python example_xta_macbps22.py 0 0 sup2sub sub2sup Subordinate AP has received XID '1279875137.84ab3fdb762742a096a8181043938232.e107cfeee0661d23da9322f1ee73faba' from superior AP Subordinate AP has created a branch with XID '1279875137.84ab3fdb762742a096a8181043938232.e107cfeee0661d2397f7336b2f6449f2' PostgreSQL, executing >DELETE FROM authors WHERE id=1921< Subordinate AP has returned 'ROLLBACK' to superior AP tiian@ubuntu1404-64:~/tmp$ |
check MySQL table content:
[Shell terminal session - MySQL] |
mysql> select * from authors; +------+-----------+-------------+ | id | last_name | first_name | +------+-----------+-------------+ | 1898 | Remarque | Erich Maria | | 1919 | Levi | Primo | +------+-----------+-------------+ 2 rows in set (0.00 sec) mysql> |
check PostgreSQL table content:
[Shell terminal session - PostgreSQL] |
testdb=> select * from authors; id | last_name | first_name ------+--------------+------------ 1921 | Rigoni Stern | Mario (1 row) testdb=> |
delete rows and commit:
[Shell terminal session - AP1] |
tiian@ubuntu1404-64:~/tmp$ python example_xta_macbps21.py 1 0 sup2sub sub2sup MySQL, executing >DELETE FROM authors WHERE id=1919< Superior AP has sent XID '1279875137.284ca606ec594b94a98a26a0e2e6730a.e107cfeee0661d23da9322f1ee73faba' to subordinate AP Superior AP has received 'PREPARED_for_COMMIT' reply from subordinate AP MySQL, executing >DELETE FROM authors WHERE id=1898< Superior AP has committed its branch tiian@ubuntu1404-64:~/tmp$ |
[Shell terminal session - AP2] |
tiian@ubuntu1404-64:~/tmp$ python example_xta_macbps22.py 1 0 sup2sub sub2sup Subordinate AP has received XID '1279875137.284ca606ec594b94a98a26a0e2e6730a.e107cfeee0661d23da9322f1ee73faba' from superior AP Subordinate AP has created a branch with XID '1279875137.284ca606ec594b94a98a26a0e2e6730a.e107cfeee0661d23759dd6e4f8ad4afc' PostgreSQL, executing >DELETE FROM authors WHERE id=1921< Subordinate AP has returned 'PREPARED_for_COMMIT' to superior AP tiian@ubuntu1404-64:~/tmp$ |
check MySQL table content:
[Shell terminal session - MySQL] |
mysql> select * from authors; Empty set (0.00 sec) mysql> |
check PostgreSQL table content:
[Shell terminal session - PostgreSQL] |
testdb=> select * from authors; id | last_name | first_name ------+--------------+------------ (0 rows) testdb=> |
Source code for programs example_xta_macbps21.py
and example_xta_macbps22.py
are
installed in directory
/opt/lixa/share/doc/lixa-X.Y.Z/examples/xta/python
and
are available on GitHub. Source code is fully
commented for readability.
[50] This must not be confused with a specific RPC technology: any communication technique that supports a request-response protocol can be used.
[51] Oracle (R) Database, JDBC Developer's Guide, 12c Release 1 (12.1); there are analogous documents for different Oracle Database's versions