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 |
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
The pattern can not be implemented using the
standard TX Transaction Demarcation interface
[49].
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
The dashed red rectangle highlights the XA global transaction.
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
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.
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.
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...
The supplied example (example_xta_macc01.c
) uses
Oracle in the role of “Resource Manager 1”; please
refer to the instructions explained:
in the section called “Remote configuration (Instant Client) and OCI” to set-up the correct client/server configuration for Oracle
in the section called “Starting the state server (lixad)” to start up the LIXA state server
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 |
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 |
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 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.
The supplied example (example_xta_macc11.cpp
) uses
Oracle in the role of “Resource Manager 1”; please
refer to the instructions explained:
in the section called “Remote configuration (Instant Client) and OCI” to set-up the correct client/server configuration for Oracle
in the section called “Starting the state server (lixad)” to start up the LIXA state server
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 |
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 |
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 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.
The supplied example (ExampleXtaMACC31.java
) uses
Oracle in the role of “Resource Manager 1”; please
refer to the instructions explained:
in the section called “Remote configuration (Instant Client) and OCI” to set-up the correct client/server configuration for Oracle
in the section called “Starting the state server (lixad)” to start up the LIXA state server
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$ 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 |
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')< |
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< |
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 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.
[49] 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)