I have two level access to database: the first with Hibernate, the second with JDBC. The JDBC level work with nontransactional tables (I use MyISAM for speed). I want make both levels works within transaction. I read about JTA which can manage distributed transactions. But there is lack information in the internet about how to implement and use custom resource.
Does any one have experience with using custom XAResources?
I want make both levels works within transaction.
Then you'll have to change your storage engine for InnoDB, MyISAM tables do not support transactions (technically, you won't get an error but a rollback won't rollback anything).
Does any one have experience with using custom XAResources?
I'm not sure to understand what you're talking about. The only XA resource I see here is your database and you don't need to implement anything custom. What you need to do is to use XA connections very likely obtained from two XA DataSources (which are supported by MySQL Connector/J 5.0.0+), use the JTA API and let the Transaction Manager do its job .
But to be honest, you should really clarify your requirements. There might be other (and easier) options than using XA. And if all the above sounds like Chinese, then I have the feeling that don't use XA would be a good advice here.
Connection are obtained via a DataSource that can be configured to support distributed transaction or not. To use multiple connections in a distributed transaction, you must configure the multiple DataSource to support XA and return XA connections.
That said, you need several physical connections only if you connects to different database, which doesn't seem to be your case (that's not clear in the question).
A DataSource can be smart enough to make sure that the same physical connection is used as long as you are in the same thread; each time you ask for a connection, it actually returns a "handle" to the same physical connection, and the physical connection returns to the pool when all handles have been closed. (But that depends on the DataSource implementation).
Hibernate per se is not an XA resource: it uses underlying a connection obtained via a DataSource. But it hooks itself in the transaction manager via JTA, in particular to flush all pending changes before the distributed transaction commits.
You can most of the time obtain the underlying connection used by the EntityManager using implementation specific API (it's at least possible with Hibernate). This means that you can maybe fulfill your requirement without using JTA and XA at all: use the underlying connection of the EntityManager for your JDBC stuffs.
In summary:
No need to mess with XAResource
Switch to InnoDB
You can try to switch to a XA DataSource and obtain a connection with DataSource.getConnection()
You can try to switch to a XA DataSource and obtain the underlying EntityManager connection
You can try to stick with a non-XA DataSource and obtain the underlying EntityManager connection
Hope I understood your question right and that it helps.
Related
I want to use teradata data source in global transaction in websphere 9.0 along with oracle XA datasource.
I am trying to figure out how to setup teradata as XA datasource, is there specific implementation class similar to oracleConnectionpooldatasource vs oracleXAdatasource? Do we have an equivalent XA datasource implemenation for TeraConnectionPoolDataSource? Is there connection pool property we can set?
Thanks
The Teradata JDBC Driver Reference documents only TeraConnectionPoolDataSource (which implements javax.sql.ConnectionPoolDataSource) and TeraDataSource (which implements javax.sql.DataSource). This leads me to believe that they do not provide an implementation of javax.sql.XADataSource.
That said, it is possible in WebSphere Application Server, at the cost of certain trade-offs, to have a data source which doesn't implement javax.sql.XADataSource participate in a global transaction alongside two-phase commit capable resources (such as the Oracle XADataSource). To do this, you must be willing to accept the possibility that if an outage or other interruption occurs after the point where the two-phase resources have completed the prepare phase when the one-phase resource (TeraData in this case) is told to commit/roll back, then the transaction manager will not know the outcome of the one-phase resource, and will be unable to automatically determine the outcome during XA recovery, such that resolution of the transaction will require manual intervention. This capability is often referred to as "Last Participant Support" (due to placement of the one-phase resource as the last resource after all of the all of the two-phase resources complete the prepare phase), and is also referred to as "Accept Heuristic Hazard" (due to the situation described earlier in this response where there is uncertain outcome).
I'm trying to understand the use of Java XA Datasource.
But I can't still figure when to use it, and when not to use it.
I read that XA Datasource used when we use two databases.
But I'm not sure what is the meaning of two database.
For example:
I had two layer of classes (Service and DAO)
A method in service layer annotated as a transaction, invoke two methods in DAO.
Each method in DAO open new connection to database and close it in the end of the method.
If I use one instance of database, and each method in DAO write to different table, do I have to use XA Datasource? since transaction occured in service layer but only in one instance database
Systems such as databases, but also for example queueing systems that you use through JMS have the concept of transactions. A transaction is treated as a unit of work; at the end of doing the work, such as inserting, updating or deleting records in the database, you commit the transaction and then the database definitively does the work; or you rollback the transaction and then everything done in the transaction is cancelled.
In some cases, your software has to perform operations over multiple different systems. For example, you might need to insert data into multiple databases, or insert something in the database and put a message on a queue.
If you want to do such combinations of operations as if they are in one transaction, then you need a distributed transaction system - a system that can combine the transactions of the different systems into one. That way you can write your code as if it's running inside a single transaction; the distributed transaction system automatically commits or rolls back the transactions in the underlying systems.
To make it more concrete: Suppose that you insert a record in a database, and put a message on a queue, and you want to do this inside one transaction. When something goes wrong with putting the message on the queue, you also want the database transaction to be rolled back, so that you don't have a record in the database but not a corresponding message on the queue. Instead of manually keeping track of the transactions of the database and the queue system (including handling all combinations of possible errors), you can use a distributed transaction system.
XA is a standard for working with distributed transactions. You can work with XA transactions in Java through the Java Transaction API (JTA). Java EE servers have support for this built-in. If you're not using a Java EE server, then you can use a separate library that implements JTA such as Narayana or Atomikos.
Each method in DAO open new connection to database and close it in the end of the method.
Normally this isn't how you should write DAOs. Opening a database connection is a relatively slow operation; if you open a new database connection for every method that you call in a DAO, your program is most like going to run slowly. You should at least use a connection pool, that manages a number of database connections and allows you to reuse already open connections.
If I use one instance of database, and each method in DAO write to different table, do I have to use XA Datasource? since transaction occured in service layer but only in one instance database
If your DAO methods each open their own connection, then they will run in separate transactions. Whether this is a problem or not depends on what your application needs to do. An XA datasource is not the solution to make them run in one transaction. Instead, you should both let them use the same connection and transaction.
XA transactions are really only useful if you are using multiple database systems or other systems, and you want to be able to perform transactions that span across these systems.
My project connects to a database using hibernate, getting connections from a connection pool on JBoss. I want to replace some of the reads/writes to tables with publish/consume from queues. I built a working example that uses OracleAQ, however, I am connecting to the DB using:
AQjmsFactory.getQueueConnectionFactory followed by createQueueConnection,
then using createQueueSession to get a (JMS) QueueSession on which I can call createProducer and createConsumer.
So I know how to do what I want using a jms.QueueSession. But using hibernate, I get a hibernate.session, which doesn't have those methods.
I don't want to open a new connection every time I perform an action on a queue - which is what I am doing now in my working example. Is there a way to perform queue operations from a hibernate.session? Only with SQL queries?
I think you're confusing a JMS (message queue) session with a Hibernate (database) session. The Hibernate framework doesn't have any overlap with JMS, so it can't be used to do both things.
You'll need 2 different sessions for this to work:
A Hibernate Session (org.hibernate.Session) for DB work
A JMS Session (javax.jms.Session) to to JMS/queue work
Depending on your use case, you may also want an XA transaction manager to do a proper two-phase commit across both sessions and maintain transactional integrity.
I was also looking for some "sane" way how to use JMS connection to manipulate database data. There is not any. Dean is right, you have to use two different connections to the same data and have distributed XA transaction between them.
This solution opens a world of various problems never seen before. In real life distributed transactions can really be non-trivial. Surprisingly in some situations Oracle can detect that two connections are pointing into the same database and then two-phase commit can be bypassed - even when using XA.
I'm reading Java Persistence with Hibernate, and I found the following text.
Today, high-quality standalone JTA providers such as Bitronix (used for the example code of this book) and Atomikos are available and easy to install in any Java environment. Think of these solutions as JTA-enabled database connection pools.
As I understand, JTA providers have their own connection pools.
So, do they integrate (how, if they do) with connection pools like HikariCP and C3P0? Thank you.
The answer is NO, you cannot combine JTA provider with these JDBC Connection Pools.
The short reason is:
The JTA provider need XADataSource and the JDBC Connection Pools named by you just have standard DataSource.
The longer reason is:
With a JTA provider you want to handle global transactions - global means over different DataSources. (e.g. your operation wants to do something in database/DataSource 1 and something in database/DataSource 2 - if one of these parts fail, you want both parts to get rolled back as if nothing has happened to both databases/DataSources) This is done by Two-Phase-Commit and this needs a XADataSource.
Your JDBC connection pools are lightweight for applications using only one DataSource - for this applications you do not need JTA (even if you can use them either, of course).
I am using Oracle and Teradata both databases in my Java based project. I want to setup global transaction so that I can perform operations on both the Database under one transaction.
For global transactions such as JTA or atomikos database must have XA driver support. But as my findings Teradata doesn't have XA driver.
So now how could I setup the global transaction and performance operations on both database under 1 transaction?
why would you want to do that?
If you use terradata as a data warehouse, you could feed it in a separate, asynchronous process.
That being said, you don't strictly need an XA driver to run as part of a JTA transaction. Of course, not doing so leads you to make some compromise, especially in case of recovery.
All JTA-aware transaction managers I know have the notion of Last Resource Commit (or LRC, check this page for more details). You could configure your Teradata datasource as LRC.
Resources
Bitronix config
Atomikos config
If you use oracle and the teradata database, you need to configure the oracle database gateway to support distributed transactions. In that you will not use XA, but you will use distributed transactions with two-phase commit.