[#7647] ticket:669 Fix race condition in artifact versioning
diff --git a/Allura/allura/model/artifact.py b/Allura/allura/model/artifact.py
index ccb6b42..4632301 100644
--- a/Allura/allura/model/artifact.py
+++ b/Allura/allura/model/artifact.py
@@ -471,7 +471,6 @@ class __mongometa__:
 
     def commit(self, update_stats=True):
         '''Save off a snapshot of the artifact and increment the version #'''
-        self.version += 1
         try:
             ip_address = request.headers.get(
                 'X_FORWARDED_FOR', request.remote_addr)
@@ -483,18 +482,28 @@ def commit(self, update_stats=True):
             artifact_class='%s.%s' % (
                 self.__class__.__module__,
                 self.__class__.__name__),
-            version=self.version,
             author=dict(
                 id=c.user._id,
                 username=c.user.username,
                 display_name=c.user.get_pref('display_name'),
                 logged_ip=ip_address),
-            timestamp=datetime.utcnow(),
             data=state(self).clone())
-        ss = self.__mongometa__.history_class(**data)
-        session(ss).insert_now(ss, state(ss))
+        while True:
+            self.version += 1
+            data['version'] = self.version
+            data['timestamp'] = datetime.utcnow()
+            ss = self.__mongometa__.history_class(**data)
+            try:
+                session(ss).insert_now(ss, state(ss))
+            except pymongo.errors.DuplicateKeyError:
+                log.warning('Trying to create duplicate version %s of %s',
+                            self.version, self.__class__)
+                session(ss).expunge(ss)
+                continue
+            else:
+                break
         log.debug('Snapshot version %s of %s',
-                 self.version, self.__class__)
+                  self.version, self.__class__)
         if update_stats:
             if self.version > 1:
                 g.statsUpdater.modifiedArtifact(