I have a C++ program that manages and uses a pool of database connections (pointing to different databases). Is there a way for the work done on these connections to be part of a global transaction started in Tyrex? Can I enlist a XAResource that points to the db I am going to use in my C++ program, acquire the XID from the transaction manager, associate the work done in my C++ program with the same XID and ask Tyrex to coordinate commit/rollback?
Thanks a lot!
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
You can create a transaction in Tyrex using the JTS transaction factory. Then register the C++ database connections as Corba resources using the JTS Coordinator from the Control object returned by the transaction factory. Then you can use the Terminator fron the Control to commit or rollback. Take a look at the JTS spec on the Javasoft website
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Anonymous
-
2002-09-06
Thanks for your answer!
My C++ program is not based on CORBA and we don't want to buy an orb which adds dependency to our architecture. Is there any solution other than going with a CORBA architecture?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Yes you can follow the steps that you outlined previously:
1) Start a transaction in Tyrex
2) Register the database connections in the Tyrex transaction
3) Get the xid from the transaction
4) In your C++ program get the XAResource for the database connection and call start on the XAResource with that xid
5) Use the C++ connection
6) Call C++ XAResource end for the connection
7) Tyrex commit
The XA support in C++ is different from that in Java so steps 4 and 6 you'll need to double-check those steps.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Anonymous
-
2002-09-06
Thanks Riad, your confirmation is really a relief for me. It'll give me some momentum to start prototyping.
For the list of items to perform, I am not sure about the following details:
(a) After I start a transaction in Tyrex, I only have UserTransaction interface, how should I perform the second step "registering the database connections" - do I have to open a JDBC connection so that the corresponding XAResource interface is registered with the transaction manager, or there is another API for doing so?
(b) For step 3) "getting XID from the transaction", what API can I use? It's not accessible from UserTransaction interface.
(c) The data section of xid_t is comprised of two parts according to XA Specification - gtrid and bqual. I am assuming the bqual part is different for different resources within the same transaction. How do I acquire the XID for different resources?
(d) Once I performed step 4), how does the database server know that the connections I am going to use are for this transaction? Is it because the thread using the connection is the same thread performing xa_start(XID)?
Much appreciation for your help!
Thanks,
Jian
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
a) I'm not sure how you're accessing Tyrex but you can register the database connections yourself like:
tyrex.tm.TransactionDomain txDomain = tyrex.tm.TransactionDomain.getDomain( "default" ); // default is the usual name in the tyrex domain.xml file
javax.transaction.TransactionManager tm = txDomain.getTransactionManager();
javax.transaction.Transaction tnx = tm.getTransaction();
javax.sql.XADataSource xaDataSource = <datasource>;
javax.sql.XAConnection xaConnection = xaDataSource.getConnection();
tnx.enlistResource(xaConnection.getXAREsource());
b) To get the xid you'll need the actual transaction object as above:
javax.transaction.xa.Xid xid = ((tyrex.tm.TyrexTransaction)tnx).getXid();
c) No the bqual refers to different branches within the same global transaction. You can use the same xid_t with different resources. You'll most likely have to deteemine whether you are starting a new transaction or joining an existing transaction for the C++ resources. For example if all your resources come from the same database then the first resource is "started" with the xid and the subsequent resources are "joined". Take a look at the JTA spec (http://java.sun.com/products/jta/) for javax.transaction.XAResource.start for more details
d) The database would know which connections are being used for this transaction because you registered the xid with the database. So if you use an unregistered connection then that work won't be part of the transaction.
The thread association would be managed by the transaction manager but since you're not using a C++ tm there is no thread association.
Again I'm not familiar with the XA spec so please correct me if I'm wrong.
Riad
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Anonymous
-
2002-09-07
Hi Riad,
I think I am still confused about d).
About your comment "So if you use an unregistered connection then that work won't be part of the transaction", in my C++ program, what is considered a "registered connection" and what is an "unregistered connection"? All that I do is to call xa_start(XID) (for once) and then use the connections. What's the link between a "connection" and the XAResource interface which contains just an array of function pointers?
Also, if the thread association is done by TM, which is not controlling my C++ program, then there must be something broken in my C++ program (whatever the functionality the transaction manager tries to maintain using thread association), right?
Am I making any sense?
Thanks,
Jian
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I dug up a copy of the XA spec. I'm assuming that dynamic registrations of RM do not occur. It seems that calling xa_start associates the thread with the RM so any connections used in that thread are associated with the xid. You just have to call xa_end in the same thread. This different from the JTA where the thread association is done by the TM so please ignore my previous comments about the XA spec.
Riad
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I have a C++ program that manages and uses a pool of database connections (pointing to different databases). Is there a way for the work done on these connections to be part of a global transaction started in Tyrex? Can I enlist a XAResource that points to the db I am going to use in my C++ program, acquire the XID from the transaction manager, associate the work done in my C++ program with the same XID and ask Tyrex to coordinate commit/rollback?
Thanks a lot!
You can create a transaction in Tyrex using the JTS transaction factory. Then register the C++ database connections as Corba resources using the JTS Coordinator from the Control object returned by the transaction factory. Then you can use the Terminator fron the Control to commit or rollback. Take a look at the JTS spec on the Javasoft website
Thanks for your answer!
My C++ program is not based on CORBA and we don't want to buy an orb which adds dependency to our architecture. Is there any solution other than going with a CORBA architecture?
Yes you can follow the steps that you outlined previously:
1) Start a transaction in Tyrex
2) Register the database connections in the Tyrex transaction
3) Get the xid from the transaction
4) In your C++ program get the XAResource for the database connection and call start on the XAResource with that xid
5) Use the C++ connection
6) Call C++ XAResource end for the connection
7) Tyrex commit
The XA support in C++ is different from that in Java so steps 4 and 6 you'll need to double-check those steps.
Thanks Riad, your confirmation is really a relief for me. It'll give me some momentum to start prototyping.
For the list of items to perform, I am not sure about the following details:
(a) After I start a transaction in Tyrex, I only have UserTransaction interface, how should I perform the second step "registering the database connections" - do I have to open a JDBC connection so that the corresponding XAResource interface is registered with the transaction manager, or there is another API for doing so?
(b) For step 3) "getting XID from the transaction", what API can I use? It's not accessible from UserTransaction interface.
(c) The data section of xid_t is comprised of two parts according to XA Specification - gtrid and bqual. I am assuming the bqual part is different for different resources within the same transaction. How do I acquire the XID for different resources?
(d) Once I performed step 4), how does the database server know that the connections I am going to use are for this transaction? Is it because the thread using the connection is the same thread performing xa_start(XID)?
Much appreciation for your help!
Thanks,
Jian
Hi Jian,
a) I'm not sure how you're accessing Tyrex but you can register the database connections yourself like:
tyrex.tm.TransactionDomain txDomain = tyrex.tm.TransactionDomain.getDomain( "default" ); // default is the usual name in the tyrex domain.xml file
javax.transaction.TransactionManager tm = txDomain.getTransactionManager();
javax.transaction.Transaction tnx = tm.getTransaction();
javax.sql.XADataSource xaDataSource = <datasource>;
javax.sql.XAConnection xaConnection = xaDataSource.getConnection();
tnx.enlistResource(xaConnection.getXAREsource());
b) To get the xid you'll need the actual transaction object as above:
javax.transaction.xa.Xid xid = ((tyrex.tm.TyrexTransaction)tnx).getXid();
c) No the bqual refers to different branches within the same global transaction. You can use the same xid_t with different resources. You'll most likely have to deteemine whether you are starting a new transaction or joining an existing transaction for the C++ resources. For example if all your resources come from the same database then the first resource is "started" with the xid and the subsequent resources are "joined". Take a look at the JTA spec (http://java.sun.com/products/jta/) for javax.transaction.XAResource.start for more details
d) The database would know which connections are being used for this transaction because you registered the xid with the database. So if you use an unregistered connection then that work won't be part of the transaction.
The thread association would be managed by the transaction manager but since you're not using a C++ tm there is no thread association.
Again I'm not familiar with the XA spec so please correct me if I'm wrong.
Riad
Hi Riad,
I think I am still confused about d).
About your comment "So if you use an unregistered connection then that work won't be part of the transaction", in my C++ program, what is considered a "registered connection" and what is an "unregistered connection"? All that I do is to call xa_start(XID) (for once) and then use the connections. What's the link between a "connection" and the XAResource interface which contains just an array of function pointers?
Also, if the thread association is done by TM, which is not controlling my C++ program, then there must be something broken in my C++ program (whatever the functionality the transaction manager tries to maintain using thread association), right?
Am I making any sense?
Thanks,
Jian
Hi Jian,
I dug up a copy of the XA spec. I'm assuming that dynamic registrations of RM do not occur. It seems that calling xa_start associates the thread with the RM so any connections used in that thread are associated with the xid. You just have to call xa_end in the same thread. This different from the JTA where the thread association is done by the TM so please ignore my previous comments about the XA spec.
Riad