I am currently retrieving both a UserTransaction and a DataSource from a Weblogic 10.3 server using JNDI.
I have set the Datasource up to 'Support Global Transactions' and to use 'Logging Last Resource'
My hope was that by beginning a UserTranscation and then retrieving a JDBC connection from the Datasource the connection would participate in the Transaction.
This does not appear to be the case, and my insert statements are being commited straight away and rolling back the transaction does not have any effect.
Are my above assumptions correct?
Can anyone point me in the direction of some documentation or samples on how to achieve this?
Many thanks in advance
UPDATE:
As requested here is a skeleton outline of the code I am using:
private void doSomething() {
Connection conn = null;
try {
Hashtable env = new java.util.Hashtable();
env.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory");
env.put(javax.naming.Context.PROVIDER_URL,"t3://localhost:8080");
InitialContext ctx = InitialContext(env));
UserTransaction transaction = null;
transaction = (UserTransaction) ctx.lookup("java:comp/UserTransaction");
DataSource dataSource = (DataSource) context.lookup("jdbc/xxxxx/DataSource");
conn = dataSource.getConnection();
transaction.begin();
// JDBC code goes here
transaction.commit();
} catch(Exception e) {
// TODO
if (transaction != null) {
try {
transaction.rollback();
} catch (Exception ex) {
// TODO
}
} finally {
if (con != null) {
conn.close
}
}
}
UPDATE 2:
In order to resolve this issue I had to do 2 things:
Change the order of the code to firstly begin the user transaction and then get a connection from the Datastore (as pointed out by Pascal Thivent).
Change the Datasource referenced by '"jdbc/xxxxx/DataSource"' to an XADatasource. This is because I was calling code inside the user transaction that used another Datasource that was already configured to support LLR and as pointed out by Pascal Thivent below you can only have one LLR Datasource participate in a transcation.
I have accepted Pascal Thivent's answer below because it explained both of these issues.
Yes, your assumptions are correct and, according to Create LLR-enabled JDBC data sources, your data source seems properly configured.
Do you get the connection after starting the user transaction? Can you show your code or pseudo code?
UPDATE: As mentioned in Programming Considerations and Limitations for LLR Data Sources:
- When programming with an LLR data source, you must start the global transaction before calling getConnection on the LLR data source. If you call getConnection before starting the global transaction, all operations on the connection will be made outside of the global transaction.
So, could you try this:
transaction.begin(); //start the global tx before calling getConnection()
conn = dataSource.getConnection();
...
transaction.commit();
UPDATE2: Not sure to understand from where the 2nd connection is comming (your pseudo code isn't showing this). However, according to the same Programming Considerations and Limitations for LLR Data Sources:
- Only instances of a single LLR data source may participate in a particular transaction. A single LLR data source may have instances on multiple WebLogic servers, and two data sources are considered to be the same if they have the same configured name. If more than one LLR data source instance is detected and they are not instances of the same data source, the transaction manager will roll back the transaction.
Actually, without a fully representative example, I feel a bit like walking in the dark :)