hi,
If two resources are involved in a transaction then the XA transation
setting should be enabled in the weblogic server. Then the xa drivers
has to be chosed.Is there a alternative way to have this two
resources in a transaction without enabling XA transaction
Yes, you can use Global Transaction Emulation. WebLogic has two mode:
Logging Last Resource - WebLogic creates a table into all your datasources and write transactions data into this table. This is a preference option.
From official documentation:
With this option, the transaction branch in which the connection is used is processed as the >last resource in the transaction and is processed as a local transaction. Commit records for >two-phase commit (2PC) transactions are inserted in a table on the resource itself, and the >result determines the success or failure of the prepare phase of the global transaction. >This option offers some performance benefits and greater data safety than Emulate Two-Phase >Commit, but it has some limitations.
see http://docs.oracle.com/cd/E15051_01/wls/docs103/jta/llr.html
Emulate Two-Phase Commit - transaction branch always return "SUCCESS" while prepare phase. Select this option if your app can tolerant heuristic conditions.
see http://docs.oracle.com/cd/E23943_01/web.1111/e13737/transactions.htm for more information.
I prefer LLR option, but if you work with legacy DB and do not have the table create grant, you should use two-phase commit emulation.
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).
In my standalone java application, jms and hibernate are used for fulfilling my requirements. I used the JTA transaction manager for the transaction management purposes. Can i enlist the XAResource for the hibernate and jms in the jta transaction to ensure the atomicity of my application.
Yes, it's possible. Called sometimes two-phase commit, it synchronises transactions between multiple resources.
First of all make sure you're RDBMS supports and has the feature turned on. In PostgreSQL, for example, this means setting the max_prepared_transactions configuration parameter from postgresql.conf to something above 0.
Also, make sure the JMS queue you're using support this transaction method. In Wildfly this means adding transaction="xa" on pooled-connection-factory.
My Websphere application has 3 datsources. Two of them are XA and the other is non-XA.
I have made a Java method transactional by annotating the method with #transactional annotation.
Within the method, 3 tasks are performed. The first one is using one XA datasource to do some update, then the second one uses the non-XA datasource to select a few records and the final task uses another XA datasource to do some update again.
However, an exception is thrown with the following error:
An illegal attempt to commit a one phase capable resource with existing two phase capable resources
I want to know why the above error occurs even my application just uses the non-XA to select some data and no commit is required and how I can get rid of the problem if I am not allowed to change the non-XA datasource to XA.
The non-XA resource cannot by default participate in a distributed transaction. So you have the following options:
Change datasource to XA - you wrote that you cannot do that
Try to enable Last Participant Support - Last participant support is an extension to the transaction service that enables a single one-phase resource to participate in a two-phase transaction with one or more two-phase resources.
Set this (nonXA) datasource to be non transactional, if you don't need transactions for it. It will not be enlisted in the transaction:
Select Resources > JDBC > Data sources
Select the name of the data source that you want to configure.
Select WebSphere Application Server data source properties from the Additional Properties heading.
Select Non-transactional data source.
Click OK.
wrap that nonXA call in EJB, and mark it as not supporting transactions.
Manually manage transaction - don't use container managed transaction, but handle transaction inside your method manually using Transaction API.
when starting the second task, the previous task which does updates on a XA datasource need to be commit or rolled back while you are using #Transaction annotation the whole tasks automatically go through one transaction so don't use #Transaction annotation and instead of it put each task inside separate transaction
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.
I wan to know how the transaction is internally implemented in EJB. I want to know the logic they use to create a transaction. if you could point out some articles that would be helpful
Hibernate doesn't implement transactions, it relies on and wraps JDBC transactions or JTA transactions (either container managed or application managed).
Regarding EJBs, if you want to understand the details of a JTA Transaction Manager, you'll need to be fluent with the JTA interfaces UserTransaction, TransactionManager, and XAResource which are described in the JTA specification. The JDBC API Tutorial and Reference, Third Edition will also be useful to understand the XA part of a JDBC driver.
Then, get the sources of an EJB container (like JBoss) or of a standalone JTA Transaction Manager (like Atomikos) to analyze the TM part. And good luck.
This question could have answers at many levels.
A general discussion of what's going on can be found here
My summary goes like this ... First, somewhere there must be a transaction coordinator, the EJB container will know about the coordinator - typically that's part of the application server. So all the EJB container has to do is to call
someobject.BeginTransaction()
that's it. The actual API the EJB container uses is JTA. EJBs can actually use Bean Managed transaction transaction or Container managed transactions. In the Bean Managed case the implementer nhas to make the JTA calls. More usually we use Container Managed transactions (CMT). In which case the container has logic which is run before the implementation is reached. For example:
if ( we're not already in a transaction )
begin transaction
call the EJB implementation
and later the container has logic
if ( finished processing request )
commit transaction
with other paths to abort the transaction if errors have happened.
Now that logic is more complex because CMT EJBs are annotated with transaction control statements. For example you can say things "if we already have a transaction, use it" So if one EJB calls another only a single transaction is used. Read up the EJB spec for that.
However all that's pretty obvious in any write-up of Java EE EJBs. So I suspect that you're asking moe about what happens inside the JTA calls, how the transaction manager is implemented and its relationship to the transactional resource managers (eg. Databases). That's a huge topic. You've actually go implementations of the XA distributed transaction protocol down there. Frankly I doubt that you really need to need to know this. At some point you have trust the APIs you're using. However there is one key detail: your Transaction Manager (typically the App Server itself) must be able to tell the REsource Managers the fate of any given transaction, and that information must survive restart of the App Server, hence some persistent store of transaction information must be kept. You will find transaction logs somewhere, and in setting up the App Server you need to make sure those logs are well looked after.
From EJB in Action book
The protocol commonly used to achieve multiple resource is the two-phase commit. The two-phase commit protocol performs an additional preparatory step before the final commit. Each resource manager involved is asked if the current transaction can be successfully committed. If any of the resource managers indicate that the transaction cannot be committed if attempted, the entire transaction is abandoned (rolled back). Otherwise, the transaction is allowed to proceed and all resource managers are asked to commit.
A resource manager can be a database, for instance. Others examples includes a Message Service. The component which coordinates transactions is called Transaction manager.
Suppose you have an application which involves two distincts databases. How does Transaction manager performs its work by using Two phase commit protocol ?
Transaction Manager ask database 1 if it can commit the current transaction
If so, ask database 2 if it can commit the current transaction
Transaction Manager ask database 1 to commit
Transaction Manager ask database 2 to commit
Hibernate is built on top of the JDBC API. It just coordinates one database. So if you call
session.commit();
Behind the scenes, it call
connection.commit();
If you really want to study Transaction internals, my advice is Java Transaction Processing book.
Hibernate has TransactionFactory:
An abstract factory for Transaction instances. Concrete implementations are specified by hibernate.transaction.factory_class.
It has implementations: JDBCTransactionFactory, JTATransactionFactory, CMTTransactionFactory. These factories create an instance of Transaction - for example JDBCTransaction.
Then I can't tell you what happens for JTA and CMT, but for JDBC it's as simple as setting the auto-commit to false (when you call begin a transaction):
connection.setAutoCommit(false);
And respectively on transaction.commit(): connection.commit()
If any exception occurs when operating with the session, it invokes connection.rollback()
Another good read would be the JTS articles by Brian Goetz; links:
http://www.ibm.com/developerworks/java/library/j-jtp0305.html
http://www.ibm.com/developerworks/java/library/j-jtp0410/index.html
http://www.ibm.com/developerworks/java/library/j-jtp0514.html