The Multiple Applications, Consecutive Calls 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: no, strictly consecutive executive

Description

This is a Distributed Transaction Processing pattern introduced by XTA: two or more Application Programs use the same Resource Manager(s) and perform consecutive operations inside a single XA global transaction. The Resource Manager(s) must be able to suspend and resume the thread's association with the transaction branch: this feature is part of the XA standard, but some resource managers don't support it (for example MySQL, MariaDB and PostgreSQL).

The following picture shows an example that can be implemented using Oracle RDBMS.

Figure 8.6. Example of Multiple Applications, Consecutive Calls with two Application Programs and one Resource Manager

Example of “Multiple Applications, Consecutive Calls” with two Application Programs and one Resource Manager


The pattern can not be implemented using the standard TX Transaction Demarcation interface [50].

How it works

Figure 8.7. Simplified sequence diagram for the Multiple Applications, Consecutive Calls Pattern

Simplified sequence diagram for the “Multiple Applications, Consecutive Calls” 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:

  • The first AP creates some XTA objects: a XaResource, a TransactionManager, and one Transaction

  • The first AP enlists the XA resource that must be controlled by the transaction using EnlistResource() method

  • The first AP uses the Open() method to initialize the XaResource objects

  • The first AP uses the Start() method to start a new XA distributed transaction

  • The first AP interacts with the Resource Manager using the native objects/connections/handles to operate (doSomething method in the diagram). The example is based on Oracle DBMS: environment is retrieved with xaoEnv(), context is retrieved with xaoSvcCtx() and connection handle is retrieved with OCIHandleAlloc

  • The first AP suspends its thread's association with the transaction using Suspend() method and then it retrieves the Transaction Id (XID) using GetXid() method

  • The first AP is now able to pass the Transaction Id (XID) to the second AP: it can use any type of communication protocol able to send an ASCII string

  • At this point, first AP terminates its processing and the second AP takes the control of the transaction using Resume() method

  • The second AP interacts with the Resource Manager using the native objects/connections/handles to operate (doSomething method in the diagram)

  • The second AP commit the transaction using Commit() method (alternatively it could rollback the transaction using Rollback() method)

  • The second AP terminates its processing

Note

The dashed red rectangle highlights the XA global transaction.

Important

These are the relevant elements of this pattern:

  • The first Application Program starts a new Transaction, performs some activities with the Resource Manager(s), suspends its association with the Transaction and passes the XID to the second Application Program

  • The second Application Program sets up its XTA objects, but it does not start a new Transaction: it must wait the XID from the first Application Program, resumes the Transaction and completes the work

  • The pattern does not allow concurrent access to the same Resource Manager(s): only one Application Program at a time can be associated to the same global transaction

  • There's basically no limit to the number of different Application Programs that consecutively participate into the Transaction

  • There's no constraint to the number of different programming languages used: every Application Program can be developed using a different programming language supported by XTA

  • There's no constraint to communication protocol used by Application Programs to exchange information: REST API, SOAP based web services, CORBA, RPC, any network protocol, any inter process communication, etc... XTA does not force the developer to use a specific communication protocol: any technique suitable to send an ASCII string can be used

Note

The methods listed in the above description must be considered pseudo-code: the real name and signature is language dependent. As an example,

tm = new TransactionManager()

translates to

tm = xta_transaction_manager_new()

and

tx.Commit()

translates to

xta_transaction_commit(tx, FALSE)

in C.

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.

MariaDB, MySQL and PostgreSQL support for suspend/resume

All the three databases do not support the XA specification part that describe as a transaction can be suspended and resumed. This pattern can't be used with those Resource Managers. The limitation currently applies to all the provided APIs: C, Java, etc...

An example using the C language

The supplied example (example_xta_macc01.c) uses Oracle in the role of Resource Manager 1; please refer to the instructions explained:

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 file example_xta_macc01.c in your working dir:

[Shell terminal session]
	    tiian@ubuntu:~/tmp$ cp /opt/lixa/share/doc/lixa-X.Y.Z/examples/xta/example_xta_macc01.c .
	  

Substitute X.Y.Z with the actual version of the software you installed.

Compile and link the C example program:

[Shell terminal session]
tiian@ubuntu1404-64:~/tmp$ . /opt/lixa/bin/lixa_env.sh 
tiian@ubuntu1404-64:~/tmp$ gcc example_xta_macc01.c $(lixa-config -x -c -f -l -d) \
> -I/opt/oracle/instantclient_12_1/sdk/include \
> -L/opt/oracle/instantclient_12_1 \
> -Wl,-rpath -Wl,/opt/oracle/instantclient_12_1 \
> -l clntsh -l nnz12 -o example_xta_macc01
	  

If the previous steps worked for you, you should have an executable file of name example_xta_sa01 in your current directory:

[Shell terminal session]
tiian@ubuntu1404-64:~/tmp$ ls -l
total 36
-rwxrwxr-x 1 tiian tiian 18647 mar 27 21:51 example_xta_macc01
-rw-r--r-- 1 tiian tiian 12828 mar 27 21:50 example_xta_macc01.c
	  

The example program accepts 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

  • superior (or subordinate): use 1 if you want to execute the superior part depicted in the sequence diagram (Application Program 1) or 0 if you want to execute the subordinate part depicted in the sequence diagram (Application Program 2)

  • XIDfilename: a valid name for a file that must be used to transfer XID (Transaction ID) from Application Program 1 to Application Program 2; XIDfilename can be the name of a regular file or of a FIFO (named pipe)

Open three terminal sessions: one for Application Program 1

[Shell terminal session - AP1]
tiian@ubuntu1404-64:~/tmp$ ls -la
total 44
drwxrwxr-x  2 tiian tiian  4096 mar 27 22:06 .
drwxr-xr-x 12 tiian tiian  4096 mar 27 21:52 ..
-rwxrwxr-x  1 tiian tiian 18647 mar 27 21:51 example_xta_macc01
-rw-r--r--  1 tiian tiian 12828 mar 27 21:50 example_xta_macc01.c
	  

another one for Application Program 2

[Shell terminal session - AP2]
tiian@ubuntu1404-64:~/tmp$ ls -la
total 44
drwxrwxr-x  2 tiian tiian  4096 mar 27 22:06 .
drwxr-xr-x 12 tiian tiian  4096 mar 27 21:52 ..
-rwxrwxr-x  1 tiian tiian 18647 mar 27 21:51 example_xta_macc01
-rw-r--r--  1 tiian tiian 12828 mar 27 21:50 example_xta_macc01.c
	  

and the last one for Oracle sqlplus client

[Shell terminal session - Oracle]
tiian@ubuntu1404-64:~$ . ./oracle_env.sh 
tiian@ubuntu1404-64:~$ sqlplus hr/hr@lixa_ora_db

SQL*Plus: Release 12.1.0.2.0 Production on Tue Mar 27 22:08:39 2018

Copyright (c) 1982, 2014, Oracle.  All rights reserved.

Last Successful login time: Tue Mar 27 2018 22:00:12 +02:00

Connected to:
Oracle Database 12c Standard Edition Release 12.1.0.2.0 - 64bit Production

SQL>
	  

create a FIFO (named pipe) in current directory:

[Shell terminal session - AP1]
tiian@ubuntu1404-64:~/tmp$ mkfifo xid.fifo
tiian@ubuntu1404-64:~/tmp$ ls -la
total 44
drwxrwxr-x  2 tiian tiian  4096 mar 27 22:10 .
drwxr-xr-x 12 tiian tiian  4096 mar 27 21:52 ..
-rwxrwxr-x  1 tiian tiian 18647 mar 27 21:51 example_xta_macc01
-rw-r--r--  1 tiian tiian 12828 mar 27 21:50 example_xta_macc01.c
prw-rw-r--  1 tiian tiian     0 mar 27 22:10 xid.fifo
	  

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
	  

in the first terminal session, start example_xta_macc01 in the role of AP1 and in the second terminal session, start example_xta_macc01 in the role of AP2

[Shell terminal session - AP1]
tiian@ubuntu1404-64:~/tmp$ ./example_xta_macc01 1 1 1 xid.fifo 
OCI statement >INSERT INTO authors (ID, LAST_NAME, FIRST_NAME) VALUES(1930, 'Bonatti', 'Walter')< completed
XID='1279875137.67f9ed180b7f4fe8a9d0f749a0f9e90b.5ed2d6ffa60ad419517220dd5ab2719e' has been written in file 'xid.fifo'
	  

[Shell terminal session - AP2]
tiian@ubuntu1404-64:~/tmp$ ./example_xta_macc01 1 1 0 xid.fifo 
XID='1279875137.67f9ed180b7f4fe8a9d0f749a0f9e90b.5ed2d6ffa60ad419517220dd5ab2719e' has been read from file 'xid.fifo'
OCI statement >INSERT INTO authors (ID, LAST_NAME, FIRST_NAME) VALUES(1948, 'Casarotto', 'Renato')< completed
	  

Note

Application Program 1 suspends its execution and waits Application Program 2 start: this is a consequence of the FIFO behavior

check Oracle table content:

[Shell terminal session - Oracle]
SQL> select * from authors;

ID         LAST_NAME            FIRST_NAME
---------- -------------------- --------------------
1930       Bonatti              Walter
1948       Casarotto            Renato

	  

if you start the superior and subordinate Application Program in the right order you can use even a regular file instead of the named FIFO (pipe); try to perform a SQL DELETE followed by a rollback using the name of a temporary file to use:

[Shell terminal session - AP1]
tiian@ubuntu1404-64:~/tmp$ ./example_xta_macc01 0 0 1 xid2.fifo
OCI statement >DELETE FROM authors WHERE ID=1930< completed
XID='1279875137.1f31836dab1a4081b488a9b3565faaa4.7b4180ecb8fee8c12cbc13637ab4eabb' has been written in file 'xid2.fifo'
	  

[Shell terminal session - AP2]
tiian@ubuntu1404-64:~/tmp$ ./example_xta_macc01 0 0 0 xid2.fifo
XID='1279875137.1f31836dab1a4081b488a9b3565faaa4.7b4180ecb8fee8c12cbc13637ab4eabb' has been read from file 'xid2.fifo'
OCI statement >DELETE FROM authors WHERE ID=1948< completed
	  

Note

Application Program 1 ends its execution without waiting for Application Program 2 start: this is a consequence of the regular file behavior

check Oracle table content:

[Shell terminal session - Oracle]
SQL> select * from authors;

ID         LAST_NAME            FIRST_NAME
---------- -------------------- --------------------
1930       Bonatti              Walter
1948       Casarotto            Renato

	  

as expected, the two rows are still in the table because the XA global transaction has been rolled back by Application Program 2; XA functions executed by Oracle can be inspected in its trace file:

[Shell terminal session - AP1]
tiian@ubuntu1404-64:~/tmp$ tail -n 30 /tmp/xa_NULL03272018.trc 
224024.9416.4016678528.2:
xaorollback: xid=0x4c495841-1f31836dab1a4081b488a9b3565faaa4-7b4180ecb8fee8c12cbc13637ab4eabb, rmid=0, flags=0x0


224024.9416.4016678528.2:
OCITransRollback: Attempting


224024.9416.4016678528.2:
OCITransRollback: Succeeded


224024.9416.4016678528.2:
xaorollback: rtn 0


224024.9416.4016678528.2:
xaoclose: xa_info=, rmid=0, flags=0x0


224024.9416.4016678528.2:
OCIServerDetach: Attempting


224024.9416.4016678528.2:
OCIServerDetach: Succeeded


224024.9416.4016678528.2:
xaoclose: rtn 0
	  

to complete the exercise, perform a SQL DELETE followed by a commit:

[Shell terminal session - AP1]
tiian@ubuntu1404-64:~/tmp$ ./example_xta_macc01 1 0 1 xid.fifo
OCI statement >DELETE FROM authors WHERE ID=1930< completed
XID='1279875137.bfd10e4a5fc541f587727304ae34cccf.7b4180ecb8fee8c12cbc13637ab4eabb' has been written in file 'xid.fifo'
	  

[Shell terminal session - AP2]
tiian@ubuntu1404-64:~/tmp$ ./example_xta_macc01 1 0 0 xid.fifo
XID='1279875137.bfd10e4a5fc541f587727304ae34cccf.7b4180ecb8fee8c12cbc13637ab4eabb' has been read from file 'xid.fifo'
OCI statement >DELETE FROM authors WHERE ID=1948< completed
	  

check Oracle table content:

[Shell terminal session - Oracle]
SQL> select * from authors;

no rows selected

	  

Finally the table is empty; XA functions executed by Oracle can be inspected in its trace file:

[Shell terminal session - AP1]
tiian@ubuntu1404-64:~/tmp$ tail -n 50 /tmp/xa_NULL03272018.trc 
225247.14985.1108846208.0:
xaostart: return XA_OK


225247.14985.1108846208.0:
xaoend: xid=0x4c495841-bfd10e4a5fc541f587727304ae34cccf-7b4180ecb8fee8c12cbc13637ab4eabb, rmid=0, flags=0x4000000


225247.14985.1108846208.0:
OCITransDetach: Attempting


225247.14985.1108846208.0:
OCITransDetach: Succeeded


225247.14985.1108846208.0:
xaoend: return 0


225247.14985.1108846208.0:
xaocommit: xid=0x4c495841-bfd10e4a5fc541f587727304ae34cccf-7b4180ecb8fee8c12cbc13637ab4eabb, rmid=0, flags=0x40000000


225247.14985.1108846208.0:
OCITransCommit: Attempting


225247.14985.1108846208.0:
OCITransCommit: Succeeded


225247.14985.1108846208.0:
xaocommit: rtn 0


225247.14985.1108846208.0:
xaoclose: xa_info=, rmid=0, flags=0x0


225247.14985.1108846208.0:
OCIServerDetach: Attempting


225247.14985.1108846208.0:
OCIServerDetach: Succeeded


225247.14985.1108846208.0:
xaoclose: rtn 0
	  

The trace shows that XTA performed a one phase commit instead of a two phase commit because there's only one Resource Manager (hint: function xaoprepare has not been called by the Transaction Manager).

Source Code

Source code for program example_xta_macc01.c is installed in directory /opt/lixa/share/doc/lixa-X.Y.Z/examples/xta and is available on GitHub. Source code is fully commented for readability.

An example using the C++ language

The supplied example (example_xta_macc11.cpp) uses Oracle in the role of Resource Manager 1; please refer to the instructions explained:

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 file example_xta_macc11.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_macc11.cpp .
	  

Substitute X.Y.Z with the actual version of the software you installed.

Compile and link the C++ example program:

[Shell terminal session]
tiian@ubuntu1404-64:~/tmp$ . /opt/lixa/bin/lixa_env.sh 
tiian@ubuntu1404-64:~/tmp$ g++ example_xta_macc11.cpp \
> $(lixa-config -c -f -l -d --xta --language-cpp) \
> -I/opt/oracle/instantclient_12_1/sdk/include \
> -L/opt/oracle/instantclient_12_1 -Wl,-rpath \
> -Wl,/opt/oracle/instantclient_12_1 -l clntsh -l nnz12 -o example_xta_macc11
	  

If the previous steps worked for you, you should have an executable file of name example_xta_macc11 in your current directory:

[Shell terminal session]
tiian@ubuntu1404-64:~/tmp$ ls -l
total 40
-rwxrwxr-x 1 tiian tiian 26479 ago 26 11:54 example_xta_macc11
-rw-r--r-- 1 tiian tiian 11440 ago 26 11:43 example_xta_macc11.cpp
	  

The example program accepts 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

  • superior (or subordinate): use 1 if you want to execute the superior part depicted in the sequence diagram (Application Program 1) or 0 if you want to execute the subordinate part depicted in the sequence diagram (Application Program 2)

  • XIDfilename: a valid name for a file that must be used to transfer XID (Transaction ID) from Application Program 1 to Application Program 2; XIDfilename can be the name of a regular file or of a FIFO (named pipe)

Open three terminal sessions: one for Application Program 1

[Shell terminal session - AP1]
tiian@ubuntu1404-64:~/tmp$ ls -la
total 48
drwxrwxr-x  2 tiian tiian  4096 ago 26 11:55 .
drwxr-xr-x 12 tiian tiian  4096 ago 26 11:43 ..
-rwxrwxr-x  1 tiian tiian 26479 ago 26 11:54 example_xta_macc11
-rw-r--r--  1 tiian tiian 11440 ago 26 11:43 example_xta_macc11.cpp
	  

another one for Application Program 2

[Shell terminal session - AP2]
tiian@ubuntu1404-64:~/tmp$ ls -la
total 48
drwxrwxr-x  2 tiian tiian  4096 ago 26 11:55 .
drwxr-xr-x 12 tiian tiian  4096 ago 26 11:43 ..
-rwxrwxr-x  1 tiian tiian 26479 ago 26 11:54 example_xta_macc11
-rw-r--r--  1 tiian tiian 11440 ago 26 11:43 example_xta_macc11.cpp
	  

and the last one for Oracle sqlplus client

[Shell terminal session - Oracle]
tiian@ubuntu1404-64:~$ . ./oracle_env.sh 
tiian@ubuntu1404-64:~$ sqlplus hr/hr@lixa_ora_db

SQL*Plus: Release 12.1.0.2.0 Production on Tue Mar 27 22:08:39 2018

Copyright (c) 1982, 2014, Oracle.  All rights reserved.

Last Successful login time: Sun Aug 26 2018 11:42:15 +02:00

Connected to:
Oracle Database 12c Standard Edition Release 12.1.0.2.0 - 64bit Production

SQL>
	  

create a FIFO (named pipe) in current directory:

[Shell terminal session - AP1]
tiian@ubuntu1404-64:~/tmp$ mkfifo xid.fifo
tiian@ubuntu1404-64:~/tmp$ ls -la
total 48
drwxrwxr-x  2 tiian tiian  4096 ago 26 11:58 .
drwxr-xr-x 12 tiian tiian  4096 ago 26 11:57 ..
-rwxrwxr-x  1 tiian tiian 26479 ago 26 11:54 example_xta_macc11
-rw-r--r--  1 tiian tiian 11440 ago 26 11:43 example_xta_macc11.cpp
prw-rw-r--  1 tiian tiian     0 ago 26 11:58 xid.fifo
	  

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
	  

in the first terminal session, start example_xta_macc11 in the role of AP1 and in the second terminal session, start example_xta_macc11 in the role of AP2

[Shell terminal session - AP1]
tiian@ubuntu1404-64:~/tmp$ ./example_xta_macc11 1 1 1 xid.fifo 
OCI statement >INSERT INTO authors (ID, LAST_NAME, FIRST_NAME) VALUES(1930, 'Bonatti', 'Walter')< completed
XID='1279875137.bd729d47f71b408e92c332a64502e068.7b4180ecb8fee8c12cbc13637ab4eabb' has been written to file 'xid.fifo'
	  

[Shell terminal session - AP2]
tiian@ubuntu1404-64:~/tmp$ ./example_xta_macc11 1 1 0 xid.fifo 
XID='1279875137.bd729d47f71b408e92c332a64502e068.7b4180ecb8fee8c12cbc13637ab4eabb' has been read from file 'xid.fifo'
OCI statement >INSERT INTO authors (ID, LAST_NAME, FIRST_NAME) VALUES(1948, 'Casarotto', 'Renato')< completed
	  

Note

Application Program 1 suspends its execution and waits Application Program 2 start: this is a consequence of the FIFO behavior

check Oracle table content:

[Shell terminal session - Oracle]
SQL> select * from authors;

ID         LAST_NAME            FIRST_NAME
---------- -------------------- --------------------
1930       Bonatti              Walter
1948       Casarotto            Renato

	  

if you start the superior and subordinate Application Program in the right order you can use even a regular file instead of the named FIFO (pipe); try to perform a SQL DELETE followed by a rollback using the name of a temporary file to use:

[Shell terminal session - AP1]
tiian@ubuntu1404-64:~/tmp$ ./example_xta_macc11 0 0 1 xid2.fifo
OCI statement >DELETE FROM authors WHERE ID=1930< completed
XID='1279875137.f54399449c1d409c999dc8010e7d6e9f.7b4180ecb8fee8c12cbc13637ab4eabb' has been written to file 'xid2.fifo'
	  

[Shell terminal session - AP2]
tiian@ubuntu1404-64:~/tmp$ ./example_xta_macc11 0 0 0 xid2.fifo
XID='1279875137.f54399449c1d409c999dc8010e7d6e9f.7b4180ecb8fee8c12cbc13637ab4eabb' has been read from file 'xid2.fifo'
OCI statement >DELETE FROM authors WHERE ID=1948< completed
	  

Note

Application Program 1 ends its execution without waiting for Application Program 2 start: this is a consequence of the regular file behavior

check Oracle table content:

[Shell terminal session - Oracle]
SQL> select * from authors;

ID         LAST_NAME            FIRST_NAME
---------- -------------------- --------------------
1930       Bonatti              Walter
1948       Casarotto            Renato

	  

as expected, the two rows are still in the table because the XA global transaction has been rolled back by Application Program 2; XA functions executed by Oracle can be inspected in its trace file:

[Shell terminal session - AP1]
tiian@ubuntu1404-64:~/tmp$ tail -n 30 /tmp/xa_NULL08262018.trc 
120438.18832.1685579456.0:
xaorollback: xid=0x4c495841-f54399449c1d409c999dc8010e7d6e9f-7b4180ecb8fee8c12cbc13637ab4eabb, rmid=0, flags=0x0


120438.18832.1685579456.0:
OCITransRollback: Attempting


120438.18832.1685579456.0:
OCITransRollback: Succeeded


120438.18832.1685579456.0:
xaorollback: rtn 0


120438.18832.1685579456.0:
xaoclose: xa_info=, rmid=0, flags=0x0


120438.18832.1685579456.0:
OCIServerDetach: Attempting


120438.18832.1685579456.0:
OCIServerDetach: Succeeded


120438.18832.1685579456.0:
xaoclose: rtn 0
	  

to complete the exercise, perform a SQL DELETE followed by a commit:

[Shell terminal session - AP1]
tiian@ubuntu1404-64:~/tmp$ ./example_xta_macc11 1 0 1 xid.fifo
OCI statement >DELETE FROM authors WHERE ID=1930< completed
XID='1279875137.d1c98d095a64415eb7370fc781af25d9.7b4180ecb8fee8c12cbc13637ab4eabb' has been written to file 'xid.fifo'
	  

[Shell terminal session - AP2]
tiian@ubuntu1404-64:~/tmp$ ./example_xta_macc11 1 0 0 xid.fifo
XID='1279875137.d1c98d095a64415eb7370fc781af25d9.7b4180ecb8fee8c12cbc13637ab4eabb' has been read from file 'xid.fifo'
OCI statement >DELETE FROM authors WHERE ID=1948< completed
	  

check Oracle table content:

[Shell terminal session - Oracle]
SQL> select * from authors;

no rows selected

	  

Finally the table is empty; XA functions executed by Oracle can be inspected in its trace file:

[Shell terminal session - AP1]
tiian@ubuntu1404-64:~/tmp$ tail -n 50 /tmp/xa_NULL08262018.trc 
120832.23393.3240638144.0:
xaoclose: rtn 0


120832.23394.1448613568.0:
xaoend: xid=0x4c495841-d1c98d095a64415eb7370fc781af25d9-7b4180ecb8fee8c12cbc13637ab4eabb, rmid=0, flags=0x4000000


120832.23394.1448613568.0:
OCITransDetach: Attempting


120832.23394.1448613568.0:
OCITransDetach: Succeeded


120832.23394.1448613568.0:
xaoend: return 0


120832.23394.1448613568.0:
xaocommit: xid=0x4c495841-d1c98d095a64415eb7370fc781af25d9-7b4180ecb8fee8c12cbc13637ab4eabb, rmid=0, flags=0x40000000


120832.23394.1448613568.0:
OCITransCommit: Attempting


120832.23394.1448613568.0:
OCITransCommit: Succeeded


120832.23394.1448613568.0:
xaocommit: rtn 0


120832.23394.1448613568.0:
xaoclose: xa_info=, rmid=0, flags=0x0


120832.23394.1448613568.0:
OCIServerDetach: Attempting


120832.23394.1448613568.0:
OCIServerDetach: Succeeded


120832.23394.1448613568.0:
xaoclose: rtn 0
	  

The trace shows that XTA performed a one phase commit instead of a two phase commit because there's only one Resource Manager (hint: function xaoprepare has not been called by the Transaction Manager).

Source Code

Source code for program example_xta_macc11.cpp is installed in directory /opt/lixa/share/doc/lixa-X.Y.Z/examples/xta/cpp and is available on GitHub. Source code is fully commented for readability.

An example using the Java language

The supplied example (ExampleXtaMACC31.java) uses Oracle in the role of Resource Manager 1; please refer to the instructions explained:

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 file ExampleXtaMACC31.java in your working dir:

[Shell terminal session]
tiian@ubuntu:~/tmp$ cp /opt/lixa/share/doc/lixa-X.Y.Z/examples/xta/java/ExampleXtaMACC31.java .
	  

Substitute X.Y.Z with the actual version of the software you installed.

Use the proper path for the Oracle Database jar file, then compile the Java example program with something like:

[Shell terminal session]
tiian@ubuntu1404-64:~/tmp$ javac -cp /opt/lixa/share/lixa/java/xta.jar:/opt/oracle/OJDBC-Full/ojdbc7.jar ExampleXtaMACC31.java
	  

If the previous steps worked for you, you should have a class file of name ExampleXtaMACC31.class in your current directory:

[Shell terminal session]
tiian@ubuntu1404-64:~/tmp$ ls -l
total 20
-rw-rw-r-- 1 tiian tiian 4361 gen 15 22:00 ExampleXtaMACC31.class
-rw-r--r-- 1 tiian tiian 9655 gen 15 21:57 ExampleXtaMACC31.java
	  

The example program accepts 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

  • superior (or subordinate): use 1 if you want to execute the superior part depicted in the sequence diagram (Application Program 1) or 0 if you want to execute the subordinate part depicted in the sequence diagram (Application Program 2)

  • XIDfilename: a valid name for a file that must be used to transfer XID (Transaction ID) from Application Program 1 to Application Program 2; XIDfilename can be the name of a regular file or of a FIFO (named pipe)

Open three terminal sessions: one for Application Program 1

[Shell terminal session - AP1]
tiian@ubuntu1404-64:~/tmp$ ls -la
total 28
drwxrwxr-x  2 tiian tiian 4096 gen 15 21:59 .
drwxr-xr-x 17 tiian tiian 4096 gen 15 21:52 ..
-rw-rw-r--  1 tiian tiian 4361 gen 15 22:00 ExampleXtaMACC31.class
-rw-r--r--  1 tiian tiian 9655 gen 15 21:57 ExampleXtaMACC31.java
	  

another one for Application Program 2

[Shell terminal session - AP2]
tiian@ubuntu1404-64:~/tmp$ ls -la
total 28
drwxrwxr-x  2 tiian tiian 4096 gen 15 21:59 .
drwxr-xr-x 17 tiian tiian 4096 gen 15 21:52 ..
-rw-rw-r--  1 tiian tiian 4361 gen 15 22:00 ExampleXtaMACC31.class
-rw-r--r--  1 tiian tiian 9655 gen 15 21:57 ExampleXtaMACC31.java
	  

and the last one for Oracle sqlplus client

[Shell terminal session - Oracle]
tiian@ubuntu1404-64:~$ . ./oracle_env.sh 
tiian@ubuntu1404-64:~$ sqlplus hr/hr@lixa_ora_db

SQL*Plus: Release 12.1.0.2.0 Production on Tue Mar 27 22:08:39 2018

Copyright (c) 1982, 2014, Oracle.  All rights reserved.

Last Successful login time: Sun Aug 26 2018 11:42:15 +02:00

Connected to:
Oracle Database 12c Standard Edition Release 12.1.0.2.0 - 64bit Production

SQL>
	  

create a FIFO (named pipe) in current directory:

[Shell terminal session - AP1]
tiian@ubuntu1404-64:~/tmp$ mkfifo xid.fifo
tiian@ubuntu1404-64:~/tmp$ ls -la
total 28
drwxrwxr-x  2 tiian tiian 4096 gen 15 22:06 .
drwxr-xr-x 17 tiian tiian 4096 gen 15 21:52 ..
-rw-rw-r--  1 tiian tiian 4361 gen 15 22:00 ExampleXtaMACC31.class
-rw-r--r--  1 tiian tiian 9655 gen 15 21:57 ExampleXtaMACC31.java
prw-rw-r--  1 tiian tiian    0 gen 15 22:06 xid.fifo
	  

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
	  

Warning

Oracle JDBC client requires an entropy generator as explained here; at least two options are available:
  • the parameter -Djava.security.egd=file:/dev/./urandom can be added to the command line

  • an entropy generator, like rngd has been properly configured and it's up and running

Supposing that rngs is running, in the first terminal session, start ExampleXtaMACC31 in the role of AP1 and in the second terminal session, start ExampleXtaMACC31 in the role of AP2

[Shell terminal session - AP1]
tiian@ubuntu1404-64:~/tmp$ java -Djava.library.path=/opt/lixa/lib -cp /opt/lixa/share/lixa/java/xta.jar:/opt/oracle/OJDBC-Full/ojdbc7.jar:. ExampleXtaMACC31 1 1 1 xid.fifo
Oracle, executing >INSERT INTO authors VALUES(1930, 'Bonatti', 'Walter')<
XID='1279875137.320838774dc24d13a34a70675c1b4f72.308b817e7df229ddc410d4062b9a99cb' has been written to file 'xid.fifo'
	  

[Shell terminal session - AP2]
tiian@ubuntu1404-64:~/tmp$ java -Djava.library.path=/opt/lixa/lib -cp /opt/lixa/share/lixa/java/xta.jar:/opt/oracle/OJDBC-Full/ojdbc7.jar:. ExampleXtaMACC31 1 1 0 xid.fifo
XID='1279875137.320838774dc24d13a34a70675c1b4f72.308b817e7df229ddc410d4062b9a99cb' has been read from file 'xid.fifo'
Oracle, executing >INSERT INTO authors VALUES(1948, 'Casarotto', 'Renato')<
	  

Note

Application Program 1 suspends its execution and waits Application Program 2 start: this is a consequence of the FIFO behavior

check Oracle table content:

[Shell terminal session - Oracle]
SQL> select * from authors;

        ID LAST_NAME            FIRST_NAME
---------- -------------------- --------------------
      1948 Casarotto            Renato
      1930 Bonatti              Walter

	  

if you start the superior and subordinate Application Program in the right order you can use even a regular file instead of the named FIFO (pipe); try to perform a SQL DELETE followed by a rollback using the name of a temporary file to use:

[Shell terminal session - AP1]
tiian@ubuntu1404-64:~/tmp$ java -Djava.library.path=/opt/lixa/lib -cp /opt/lixa/share/lixa/java/xta.jar:/opt/oracle/OJDBC-Full/ojdbc7.jar:. ExampleXtaMACC31 0 0 1 xid2.fifo
Oracle, executing >DELETE FROM authors WHERE id=1930<
XID='1279875137.eab32ba6aecc45e7924ac51b4e970321.308b817e7df229ddc410d4062b9a99cb' has been written to file 'xid2.fifo'
	  

[Shell terminal session - AP2]
tiian@ubuntu1404-64:~/tmp$ java -Djava.library.path=/opt/lixa/lib -cp /opt/lixa/share/lixa/java/xta.jar:/opt/oracle/OJDBC-Full/ojdbc7.jar:. ExampleXtaMACC31 0 0 0 xid2.fifo
XID='1279875137.eab32ba6aecc45e7924ac51b4e970321.308b817e7df229ddc410d4062b9a99cb' has been read from file 'xid2.fifo'
Oracle, executing >DELETE FROM authors WHERE id=1948<
	  

Note

Application Program 1 ends its execution without waiting for Application Program 2 start: this is a consequence of the regular file behavior

check Oracle table content:

[Shell terminal session - Oracle]
SQL> select * from authors;

        ID LAST_NAME            FIRST_NAME
---------- -------------------- --------------------
      1948 Casarotto            Renato
      1930 Bonatti              Walter

	  

as expected, the two rows are still in the table because the XA global transaction has been rolled back by Application Program 2. To complete the exercise, perform a SQL DELETE followed by a commit:

[Shell terminal session - AP1]
tiian@ubuntu1404-64:~/tmp$ java -Djava.library.path=/opt/lixa/lib -cp /opt/lixa/share/lixa/java/xta.jar:/opt/oracle/OJDBC-Full/ojdbc7.jar:. ExampleXtaMACC31 1 0 1 xid.fifo
Oracle, executing >DELETE FROM authors WHERE id=1930<
XID='1279875137.1015009fb4714fdb9a2545d76b369f48.308b817e7df229ddc410d4062b9a99cb' has been written to file 'xid.fifo'
	  

[Shell terminal session - AP2]
tiian@ubuntu1404-64:~/tmp$ java -Djava.library.path=/opt/lixa/lib -cp /opt/lixa/share/lixa/java/xta.jar:/opt/oracle/OJDBC-Full/ojdbc7.jar:. ExampleXtaMACC31 1 0 0 xid.fifo
XID='1279875137.1015009fb4714fdb9a2545d76b369f48.308b817e7df229ddc410d4062b9a99cb' has been read from file 'xid.fifo'
Oracle, executing >DELETE FROM authors WHERE id=1948<
	  

check Oracle table content:

[Shell terminal session - Oracle]
SQL> select * from authors;

no rows selected

	  

The table is now empty.

Source Code

Source code for program ExampleXtaMACC31.java is installed in directory /opt/lixa/share/doc/lixa-X.Y.Z/examples/xta/java and is available on GitHub. Source code is fully commented for readability.



[50] Transaction Coupling (TC) TX extensions supports the pattern with a traditional TX like interface (see Chapter 7, Developing C Application Programs with the Transaction Coupling (TC) TX extensions)