Atomikos Forum |
|
Hello together, I am receiving the following problem:
List<ResolvedProcessData> resolvedList = _processData.getResolvedProcessData(); Context ictx = new InitialContext(); _tx = (UserTransaction) ictx.lookup("java:comp/UserTransaction"); _tx.begin(); try { tx.begin(); PersistenceService pds = new PersistenceService; pds.create(_processData, resolvedList); tx.commit(); } catch (Exception e) { if (_tx != null) { int status = _tx.getStatus(); if ((status == Status.STATUS_ACTIVE) || (status == Status.STATUS_MARKED_ROLLBACK)) { _tx.rollback(); } } } Now in the create-method I create a new ResolvedProcessData dataset for every item in the list and call create for it. Because this list contains many items I often receive a transaction timeout. After I've received this transaction timeout the elements of the resolvedList that were already processed remain in the database. I think this behaviour is wrong. The tx.rollback call in the catch block is executed - but the rollback is only done when the transaction state is equal to STATUS_ACTIVE or MARKED_AS_ROLLBACK. Unfortunately the state I receive when the transaction disappears is equal to STATUS_NO_TRANSACTION - so no rollback is done (can be done). Is anybody able to explain this becaviour? I hope somebody can help me. Thank you in advance.
Hi,
thank you for your reply. My persistence config looks like this (and I assume this is the right file :) ): com.atomikos.icatch.service=com.atomikos.icatch.standalone.UserTransactionServiceFactory com.atomikos.icatch.console_file_limit=2097152 com.atomikos.icatch.console_file_count=5 com.atomikos.icatch.output_dir = ${catalina.base}/logs/ALP com.atomikos.icatch.log_base_dir = ${catalina.base}/logs/ALP com.atomikos.icatch.default_jta_timeout = 60000 com.atomikos.icatch.console_log_level=WARN I've two configured datasources that are almost the same. The only difference is that the first one ist used for user management and the other one for the application data (both of them are oracle datasources). When the problem occurs the only datasource involved is that one used for the application data. The config for the application data looks like this: <Resource name="jdbc/ALP" auth="Container" type="de.jsci.atomikos.oracle.TNSAtomikosDataSourceBean" factory="com.atomikos.tomcat.BeanFactory" uniqueResourceName="ALP" minPoolSize="1" maxPoolSize="10" xaService="tl2plan_xxx" xaDataSourceClassName="oracle.jdbc.xa.client.OracleXADataSource" xaProperties.user="xxx" xaProperties.password="xxx"/> I hope I've provided all information you need. Thank you.
The class we use is just an extension of the AtomikosDataSourceBean. Here is the source:
public final class TNSAtomikosDataSourceBean extends AtomikosDataSourceBean { //---------------------------------------------------------------------------------------------- /** The <code>serialVersionUID</code> */ private static final long serialVersionUID = 4483657636727104266L; /** The logger instance for this class. */ private static final Log LOG = LogFactory.getLog(TNSAtomikosDataSourceBean.class); /** Property name containing database URL. */ private static final String URL = "URL"; /** Property containing the service name to retrieve database URL for. */ private String _xaService; //---------------------------------------------------------------------------------------------- /** * Get service name to retrieve database URL for. * * @return Service name to retrieve database URL for. */ public String getXaService() { return _xaService; } /** * Set service name. For this name a service entry in TNSNAMES.ORA is searched. The determined * URL is added to the 'xaProperties' property. * * @param serviceName Service name to retrieve database URL for. */ public void setXaService(final String serviceName) { _xaService = serviceName; if (serviceName != null) { String url = ""; try { String tmpPath = System.getProperty("java.io.tmpdir"); TNSNamesParser tnsNames = TNSLoader.loadTNSNames(tmpPath); if (tnsNames.contains(serviceName)) { TNSService service = tnsNames.service(serviceName); TNSAddress[] addresses = service.getAddresses(); if ((addresses != null) && (addresses.length > 0)) { url = addresses[0].getConnectString(); } } else { LOG.warn("Service '" + serviceName + "' not found in TNSNAMES.ORA"); } } catch (IOException e) { LOG.warn("Failed to load TNSNAMES.ORA", e); } getXaProperties().setProperty(URL, url); } }
Hi,
1. yes, I expect a rollback but objects are written to the database anyway. Hi, OK to recap the problem: 1. you are seeing commit instead of rollback, and/or 2. you suggest the transaction status is also wrong Am I correct? If so, where do you instruct the commit in your code?
Sorry, wrong button :)
I'll try it again. 1. yes, I expect a rollback but objects are written to the database anyway. 2. I consider the transaction status to be correct as it is STATUS_NO_TRANSACTION because the transaction was closed due to the timeout. Sorry, I don't know exactly what you mean by "where do you instruct the commit in your code". The code in my first post executes the commit on the Usertransaction object. The pds.create(_processData, resolvedList); call is executed wrapped up by an transaction. It creates 2 different object types: 1. All Objects of the resolvedList are created. Thats where the timeout occurs. 2. The processData object should be persisted. But it never gets persisted because the timeout occurs before that action is called. (So I think this is correct :) ) But all the objects of the resolvedList that have already been created stay in the database and thats what I think is wrong. |