diff --git a/reviewboard/accounts/managers.py b/reviewboard/accounts/managers.py
index a83c4a44c95e2cf1abe18f73e2685f8137f95639..6e5f1927ccc574a8209859ab50db4cbc66a26f64 100644
--- a/reviewboard/accounts/managers.py
+++ b/reviewboard/accounts/managers.py
@@ -1,16 +1,30 @@
+"""Managers for accounts models."""
+
+from __future__ import annotations
+
 import logging
+from typing import Optional, TYPE_CHECKING
 
 from django.core.exceptions import MultipleObjectsReturned
 from django.db.models import Manager
-from djblets.db.managers import ConcurrencyManager
 
 from reviewboard.accounts.trophies import trophies_registry
 
+if TYPE_CHECKING:
+    from django.contrib.auth.models import User
+
+    from reviewboard.accounts.models import (
+        LocalSiteProfile,
+        Profile,
+        ReviewRequestVisit,
+    )
+    from reviewboard.site.models import LocalSite
+
 
 logger = logging.getLogger(__name__)
 
 
-class LocalSiteProfileManager(ConcurrencyManager):
+class LocalSiteProfileManager(Manager['LocalSiteProfile']):
     """Manager for Local Site profiles."""
 
     def for_user(self, user, profile, local_site, create_if_missing=False):
@@ -64,11 +78,15 @@ class LocalSiteProfileManager(ConcurrencyManager):
 
         return site_profile, is_new
 
-    def _fix_duplicate_profiles(self, user, profile, local_site):
+    def _fix_duplicate_profiles(
+        self,
+        user: User,
+        profile: Profile,
+        local_site: Optional[LocalSite],
+    ) -> LocalSiteProfile:
         """Fix the case where we end up with duplicate Local Site profiles.
 
-        Until Review Board 5.0, we were not using ConcurrencyManager for
-        LocalSiteProfile. In addition, MySQL had an issue where the
+        In old versions of Review Board and MySQL, there was an issue where the
         unique_together constraint only worked properly when the local_site
         relation was non-NULL, potentially resulting in multiple profiles.
 
@@ -120,7 +138,7 @@ class LocalSiteProfileManager(ConcurrencyManager):
         return master_profile
 
 
-class ProfileManager(Manager):
+class ProfileManager(Manager['Profile']):
     """Manager for user profiles."""
 
     def get_or_create(self, user, *args, **kwargs):
@@ -139,7 +157,7 @@ class ProfileManager(Manager):
         return profile, is_new
 
 
-class ReviewRequestVisitManager(ConcurrencyManager):
+class ReviewRequestVisitManager(Manager['ReviewRequestVisit']):
     """Manager for review request visits."""
 
     def unarchive_all(self, review_request):
diff --git a/reviewboard/accounts/models.py b/reviewboard/accounts/models.py
index 6be050a10cd6e2029ab891a0ebd4ae097e881ae7..f4f1c66c88fe18fc0edad2ae55d5e47a1c42a92d 100644
--- a/reviewboard/accounts/models.py
+++ b/reviewboard/accounts/models.py
@@ -65,8 +65,6 @@ class ReviewRequestVisit(models.Model):
     visibility = models.CharField(max_length=1, choices=VISIBILITY,
                                   default=VISIBLE)
 
-    # Set this up with a ReviewRequestVisitManager, which inherits from
-    # ConcurrencyManager to help prevent race conditions.
     objects: ClassVar[ReviewRequestVisitManager] = ReviewRequestVisitManager()
 
     def __str__(self):
diff --git a/reviewboard/reviews/managers.py b/reviewboard/reviews/managers.py
index 478dfc66be87c63d48c386df77c13f3521d6f65b..dc2906d0636e3e6e6b13e0696481eedb4c2de00c 100644
--- a/reviewboard/reviews/managers.py
+++ b/reviewboard/reviews/managers.py
@@ -11,7 +11,6 @@ from django.db import connections, router, transaction, IntegrityError
 from django.db.models import Exists, Manager, OuterRef, Q
 from django.db.models.query import QuerySet
 from django.utils.text import slugify
-from djblets.db.managers import ConcurrencyManager
 from housekeeping.functions import deprecate_non_keyword_only_args
 
 from reviewboard.deprecation import RemovedInReviewBoard80Warning
@@ -25,14 +24,19 @@ if TYPE_CHECKING:
     from reviewboard.changedescs.models import ChangeDescription
     from reviewboard.integrations.base import Integration
     from reviewboard.integrations.models import IntegrationConfig
-    from reviewboard.reviews.models import Review, ReviewRequest, StatusUpdate
+    from reviewboard.reviews.models import (
+        BaseComment,
+        Review,
+        ReviewRequest,
+        StatusUpdate,
+    )
     from reviewboard.site.models import AnyOrAllLocalSites
 
 
 logger = logging.getLogger(__name__)
 
 
-class CommentManager(ConcurrencyManager):
+class CommentManager(Manager['BaseComment']):
     """A manager for Comment models.
 
     This handles concurrency issues with Comment models.
@@ -430,7 +434,7 @@ class ReviewRequestQuerySet(QuerySet):
         return queryset
 
 
-class ReviewRequestManager(ConcurrencyManager):
+class ReviewRequestManager(Manager['ReviewRequest']):
     """
     A manager for review requests. Provides specialized queries to retrieve
     review requests with specific targets or origins, and to create review
@@ -1386,7 +1390,7 @@ class _ReviewANY:
         return '<ReviewManager.ANY>'
 
 
-class ReviewManager(ConcurrencyManager):
+class ReviewManager(Manager['Review']):
     """A manager for Review models.
 
     This handles concurrency issues with Review models. In particular, it
diff --git a/reviewboard/reviews/models/review_request_draft.py b/reviewboard/reviews/models/review_request_draft.py
index 2b4af14245cefbe7e5d53be39c9dff3869e43c04..8d2ef580d0464db53560c662c1e8c0166f6814a4 100644
--- a/reviewboard/reviews/models/review_request_draft.py
+++ b/reviewboard/reviews/models/review_request_draft.py
@@ -2,8 +2,7 @@
 
 from __future__ import annotations
 
-from datetime import datetime
-from typing import ClassVar, List, Optional, TYPE_CHECKING
+from typing import List, Optional, TYPE_CHECKING
 
 from django.contrib.auth.models import User
 from django.db import models
@@ -11,7 +10,6 @@ from django.db.models import F
 from django.utils import timezone
 from django.utils.translation import gettext, gettext_lazy as _
 from djblets.db.fields import ModificationTimestampField, RelationCounterField
-from djblets.db.managers import ConcurrencyManager
 
 from reviewboard.attachments.models import FileAttachment
 from reviewboard.changedescs.models import ChangeDescription
@@ -27,7 +25,10 @@ from reviewboard.reviews.signals import review_request_published
 from reviewboard.scmtools.errors import InvalidChangeNumberError
 
 if TYPE_CHECKING:
-    from django.db.models.manager import RelatedManager
+    from datetime import datetime
+
+    from django.db.models.fields.related_descriptors import RelatedManager
+
     from reviewboard.attachments.models import FileAttachmentSequence
     from reviewboard.reviews.models.review_request import (
         FileAttachmentState,
@@ -43,6 +44,7 @@ class ReviewRequestDraft(BaseReviewRequestDetails):
     be modified and eventually saved or discarded. When saved, the new
     details are copied back over to the originating ReviewRequest.
     """
+
     summary = models.CharField(
         _('summary'),
         max_length=BaseReviewRequestDetails.MAX_SUMMARY_LENGTH)
@@ -133,9 +135,6 @@ class ReviewRequestDraft(BaseReviewRequestDetails):
         'inactive_file_attachments',
         verbose_name=_('inactive file attachments count'))
 
-    # Set this up with a ConcurrencyManager to help prevent race conditions.
-    objects: ClassVar[ConcurrencyManager] = ConcurrencyManager()
-
     commit = property(lambda self: self.commit_id,
                       lambda self, value: setattr(self, 'commit_id', value))
 
