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