From e6c63da077835782c1a7ad120f6f7924d5e55b15 Mon Sep 17 00:00:00 2001 From: buczekp <buczekp> Date: Sat, 17 Oct 2009 18:52:26 +0000 Subject: [PATCH] [SE-154] fixed race condition - 1v SVN: 12993 --- .../ch/systemsx/cisd/yeastx/db/DBUtils.java | 32 ++++++++++++------- .../cisd/yeastx/eicml/EICML2Database.java | 13 ++++++-- 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/db/DBUtils.java b/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/db/DBUtils.java index 775f7f376a6..41884545224 100644 --- a/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/db/DBUtils.java +++ b/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/db/DBUtils.java @@ -89,20 +89,27 @@ public class DBUtils * Creates the data set based on the information given in <var>dataSet</var>. The sample and * experiment of the data set may already exist in the database. If they don't, they are created * as well. + * <p> + * NOTE: Code responsible for trying to get sample and experiment from the DB and creating them + * if they don't exist is in synchronized block and uses currently opened transaction. Then the + * transaction is closed and data set is added to the DB in second transaction. If second + * transaction will be rolled back sample and experiment created in first transaction will stay + * in the DB. */ public static void createDataSet(IGenericDAO dao, DMDataSetDTO dataSet) { - DMExperimentDTO experiment = getOrCreateExperiment(dao, dataSet); - dataSet.setExperimentId(experiment.getId()); // make sure all the ids are set correctly. - - if (dataSet.getSample() != null) + synchronized (IGenericDAO.class) { - String permId = dataSet.getSample().getPermId(); - DMSampleDTO sample; - // it may have happened that the sample has been created by another thread after - // we checked that it does not exist - synchronized (IGenericDAO.class) + DMExperimentDTO experiment = getOrCreateExperiment(dao, dataSet); + dataSet.setExperimentId(experiment.getId()); // make sure all the ids are set correctly. + + if (dataSet.getSample() != null) { + String permId = dataSet.getSample().getPermId(); + DMSampleDTO sample; + // it may have happened that the sample has been created by another thread after + // we checked that it does not exist + sample = dao.getSampleByPermId(permId); if (sample == null) { @@ -110,10 +117,13 @@ public class DBUtils sample.setExperiment(experiment); sample = createSample(dao, sample, permId); } + + sample.setExperiment(experiment); + dataSet.setSample(sample); // make sure all the ids are set correctly. } - sample.setExperiment(experiment); - dataSet.setSample(sample); // make sure all the ids are set correctly. + dao.close(true); } + long dataSetId = dao.addDataSet(dataSet); dataSet.setId(dataSetId); } diff --git a/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/eicml/EICML2Database.java b/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/eicml/EICML2Database.java index d4ee22aa905..49d8a640634 100644 --- a/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/eicml/EICML2Database.java +++ b/rtd_yeastx/source/java/ch/systemsx/cisd/yeastx/eicml/EICML2Database.java @@ -28,6 +28,7 @@ import javax.xml.parsers.ParserConfigurationException; import net.lemnik.eodsql.QueryTool; import net.lemnik.eodsql.TransactionQuery; +import org.springframework.dao.DataAccessException; import org.xml.sax.SAXException; import ch.systemsx.cisd.base.exceptions.CheckedExceptionTunnel; @@ -100,7 +101,13 @@ public class EICML2Database transaction.close(true); } catch (Throwable th) { - DBUtils.rollbackAndClose(transaction); + try + { + DBUtils.rollbackAndClose(transaction); + } catch (DataAccessException ex) + { + // Avoid this exception shadowing the original exception. + } throw CheckedExceptionTunnel.wrapIfNecessary(th); } } @@ -115,8 +122,8 @@ public class EICML2Database int permId = 0; for (String f : new File(dir).list(new EICMLFilenameFilter())) { - eicML2Database.uploadEicMLFile(new File(dir, f), new DMDataSetDTO( - Integer.toString(++permId), "sample1", "the sample name", "experiment1", + eicML2Database.uploadEicMLFile(new File(dir, f), new DMDataSetDTO(Integer + .toString(++permId), "sample1", "the sample name", "experiment1", "the experiment name")); } System.out.println((System.currentTimeMillis() - start) / 1000.0); -- GitLab