bug: Safely handle concurrent transactions on server

Change-Id: If8d01884dae0eb5b93e6c82461179ff399aeba79
diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/transaction/TxCallableFactory.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/transaction/TxCallableFactory.java
index 956da1c..c6f1a2d 100644
--- a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/transaction/TxCallableFactory.java
+++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/transaction/TxCallableFactory.java
@@ -91,8 +91,7 @@
 
          private TransactionResult doCommit() throws Exception {
             TransactionData changes = txManager.createChangeData(txData);
-            Callable<TransactionResult> callable = txDataStore.commitTransaction(getSession(), changes);
-            return callable.call();
+            return txDataStore.commitTransaction(getSession(), changes).call();
          }
       };
    }
diff --git a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/transaction/TxDataManager.java b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/transaction/TxDataManager.java
index 942cf62..c59beb7 100644
--- a/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/transaction/TxDataManager.java
+++ b/plugins/org.eclipse.osee.orcs.core/src/org/eclipse/osee/orcs/core/internal/transaction/TxDataManager.java
@@ -22,6 +22,10 @@
 import java.util.List;
 import java.util.Set;
 import org.eclipse.osee.framework.core.data.ApplicabilityId;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
 import org.eclipse.osee.framework.core.data.ArtifactId;
 import org.eclipse.osee.framework.core.data.ArtifactReadable;
 import org.eclipse.osee.framework.core.data.ArtifactTypeToken;
@@ -80,6 +84,7 @@
    private final TupleDataFactory tupleFactory;
    private final BranchCategoryDataFactory categoryFactory;
    private final TxDataLoader loader;
+   private final ConcurrentMap<Long, Lock> hotBranches = new ConcurrentHashMap<>();
 
    public TxDataManager(ExternalArtifactManager proxyManager, ArtifactFactory artifactFactory, RelationManager relationManager, TupleDataFactory tupleFactory, BranchCategoryDataFactory categoryFactory, TxDataLoader loader) {
       this.proxyManager = proxyManager;
@@ -112,6 +117,10 @@
    }
 
    public void startTx(TxData txData) {
+      Long branchId = txData.getBranchId();
+      hotBranches.putIfAbsent(branchId, new ReentrantLock());
+      Lock lock = hotBranches.get(branchId);
+      lock.lock();
       Conditions.checkExpressionFailOnTrue(txData.isCommitInProgress(), "Commit is already in progress");
       txData.setCommitInProgress(true);
       txData.setTxState(TxState.COMMIT_STARTED);
@@ -119,6 +128,8 @@
 
    public void endTx(TxData txData) {
       txData.setCommitInProgress(false);
+      Lock lock = hotBranches.get(txData.getBranchId());
+      lock.unlock();
    }
 
    public Iterable<Artifact> getForWrite(TxData txData, Iterable<? extends ArtifactId> ids) {