The Multiple Applications, Concurrent Branches/Pseudo Synchronous Pattern

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

Description

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

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.

How it works

Figure 8.9. Simplified sequence diagram for the Multiple Applications, Concurrent Branches/Pseudo Synchronous Pattern

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

Note

The dashed red rectangle highlights the XA global transaction.

Important

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

Known limitations

Note

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.

Oracle JDBC thin optimizations

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.

Important

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++.

An example using the C language

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:

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$
	  

Note

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

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.

An example using the C++ language

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:

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$
	  

Note

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

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.

An example using the Java language

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:

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$
	  

Note

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

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.

An example using the Python language

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:

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$
	  

Note

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

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