diff --git a/core/modules/locale/locale.install b/core/modules/locale/locale.install
index 9ca0d6c..2d6929b 100644
--- a/core/modules/locale/locale.install
+++ b/core/modules/locale/locale.install
@@ -258,6 +258,38 @@ function locale_update_8001() {
 }
 
 /**
+ * Remove duplicates in {locales_source}.
+ *
+ * Aggressively removes duplicates that has not already been removed by
+ * locale_update_7004() in Drupal 7.x. If a string was translated into two
+ * different things in the same language, one of them is deleted.
+ */
+function locale_update_8002() {
+  // Look up all duplicates.
+  $results = db_query("SELECT source, context FROM {locales_source} WHERE textgroup = 'default' GROUP BY source, context HAVING COUNT(*) > 1");
+
+  // For each set of duplicates, select one row that should survive, preferably
+  // one that has been translated, and delete the rest.
+  foreach ($results as $row) {
+    $lid = db_query("SELECT s.lid FROM {locales_source} s LEFT JOIN {locales_target} t ON s.lid = t.lid WHERE s.source = :source AND s.context = :context AND s.textgroup = 'default' ORDER BY translation IS NULL", array(
+      ':source' => $row->source,
+      ':context' => $row->context,
+      ))->fetchField();
+    db_delete('locales_source')
+      ->condition('source', $row->source)
+      ->condition('context', $row->context)
+      ->condition('textgroup', 'default')
+      ->condition('lid', $lid, '<>')
+      ->execute();
+  }
+
+  // Finally remove any rows from {locales_target} that refer to non-existing
+  // lids.
+  $subquery = db_select('locales_source', 't')->fields('t', array('lid'));
+  db_delete('locales_target')->condition('lid', $subquery, 'NOT IN')->execute();
+}
+
+/**
  * @} End of "addtogroup updates-7.x-to-8.x"
  * The next series of updates should start at 9000.
  */
diff --git a/core/modules/locale/locale.module b/core/modules/locale/locale.module
index 103c284..b1f89f7 100644
--- a/core/modules/locale/locale.module
+++ b/core/modules/locale/locale.module
@@ -688,12 +688,14 @@ function locale($string = NULL, $context = NULL, $langcode = NULL) {
     }
     else {
       // We don't have the source string, cache this as untranslated.
-      db_insert('locales_source')
-        ->fields(array(
+      db_merge('locales_source')
+        ->insertFields(array(
           'location' => request_uri(),
+          'version' => VERSION,
+        ))
+        ->key(array(
           'source' => $string,
           'context' => (string) $context,
-          'version' => VERSION,
         ))
         ->execute();
       $locale_t[$langcode][$context][$string] = TRUE;
