diff --git a/Shoko.Server/Scheduling/ThreadPooledJobStore.LockOverrides.cs b/Shoko.Server/Scheduling/ThreadPooledJobStore.LockOverrides.cs
new file mode 100644
index 000000000..e536e90ec
--- /dev/null
+++ b/Shoko.Server/Scheduling/ThreadPooledJobStore.LockOverrides.cs
@@ -0,0 +1,212 @@
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+using Quartz;
+using Quartz.Impl.Matchers;
+using Quartz.Spi;
+
+namespace Shoko.Server.Scheduling;
+
+public partial class ThreadPooledJobStore : IJobStore
+{
+ ///
+ /// Retrieve the for the given
+ /// .
+ ///
+ /// The key identifying the job.
+ /// The cancellation instruction.
+ /// The desired , or null if there is no match.
+ Task IJobStore.RetrieveJob(JobKey jobKey, CancellationToken cancellationToken)
+ {
+ return ExecuteInNonManagedTXLock(LockTriggerAccess, conn => RetrieveJob(conn, jobKey, cancellationToken), cancellationToken);
+ }
+
+ ///
+ /// Retrieve the given .
+ ///
+ /// The key identifying the trigger.
+ /// The cancellation instruction.
+ /// The desired , or null if there is no match.
+ Task IJobStore.RetrieveTrigger(TriggerKey triggerKey, CancellationToken cancellationToken)
+ {
+ return ExecuteInNonManagedTXLock(LockTriggerAccess, conn => RetrieveTrigger(conn, triggerKey, cancellationToken), cancellationToken);
+ }
+
+
+ ///
+ /// Get the current state of the identified .
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ Task IJobStore.GetTriggerState(TriggerKey triggerKey, CancellationToken cancellationToken)
+ {
+ return ExecuteInNonManagedTXLock(LockTriggerAccess, conn => GetTriggerState(conn, triggerKey, cancellationToken), cancellationToken);
+ }
+
+
+ ///
+ /// Retrieve the given .
+ ///
+ /// The name of the to be retrieved.
+ /// The cancellation instruction.
+ /// The desired , or null if there is no match.
+ Task IJobStore.RetrieveCalendar(string calName, CancellationToken cancellationToken)
+ {
+ return ExecuteInNonManagedTXLock(LockTriggerAccess, conn => RetrieveCalendar(conn, calName, cancellationToken), cancellationToken);
+ }
+
+ ///
+ /// Get the number of s that are
+ /// stored in the .
+ ///
+ Task IJobStore.GetNumberOfJobs(CancellationToken cancellationToken)
+ {
+ return ExecuteInNonManagedTXLock(LockTriggerAccess, conn => GetNumberOfJobs(conn, cancellationToken), cancellationToken);
+ }
+
+ ///
+ /// Get the number of s that are
+ /// stored in the .
+ ///
+ Task IJobStore.GetNumberOfTriggers(CancellationToken cancellationToken)
+ {
+ return ExecuteInNonManagedTXLock(LockTriggerAccess, conn => GetNumberOfTriggers(conn, cancellationToken), cancellationToken);
+ }
+
+ ///
+ /// Get the number of s that are
+ /// stored in the .
+ ///
+ Task IJobStore.GetNumberOfCalendars(CancellationToken cancellationToken)
+ {
+ return ExecuteInNonManagedTXLock(LockTriggerAccess, conn => GetNumberOfCalendars(conn, cancellationToken), cancellationToken);
+ }
+
+ ///
+ /// Get the names of all of the s that
+ /// have the given group name.
+ ///
+ ///
+ /// If there are no jobs in the given group name, the result should be a
+ /// zero-length array (not ).
+ ///
+ Task> IJobStore.GetJobKeys(GroupMatcher matcher, CancellationToken cancellationToken)
+ {
+ return ExecuteInNonManagedTXLock(LockTriggerAccess, conn => GetJobNames(conn, matcher, cancellationToken), cancellationToken);
+ }
+
+ ///
+ /// Determine whether a with the given identifier already
+ /// exists within the scheduler.
+ ///
+ ///
+ ///
+ /// the identifier to check for
+ /// The cancellation instruction.
+ /// true if a calendar exists with the given identifier
+ Task IJobStore.CalendarExists(string calName, CancellationToken cancellationToken)
+ {
+ return ExecuteInNonManagedTXLock(LockTriggerAccess, conn => CheckExists(conn, calName, cancellationToken), cancellationToken);
+ }
+
+ ///
+ /// Determine whether a with the given identifier already
+ /// exists within the scheduler.
+ ///
+ ///
+ ///
+ /// the identifier to check for
+ /// The cancellation instruction.
+ /// true if a Job exists with the given identifier
+ Task IJobStore.CheckExists(JobKey jobKey, CancellationToken cancellationToken)
+ {
+ return ExecuteInNonManagedTXLock(LockTriggerAccess, conn => CheckExists(conn, jobKey, cancellationToken), cancellationToken);
+ }
+
+ ///
+ /// Determine whether a with the given identifier already
+ /// exists within the scheduler.
+ ///
+ ///
+ ///
+ /// the identifier to check for
+ /// The cancellation instruction.
+ /// true if a Trigger exists with the given identifier
+ Task IJobStore.CheckExists(TriggerKey triggerKey, CancellationToken cancellationToken)
+ {
+ return ExecuteInNonManagedTXLock(LockTriggerAccess, conn => CheckExists(conn, triggerKey, cancellationToken), cancellationToken);
+ }
+
+ ///
+ /// Get the names of all of the s
+ /// that have the given group name.
+ ///
+ ///
+ /// If there are no triggers in the given group name, the result should be a
+ /// zero-length array (not ).
+ ///
+ Task> IJobStore.GetTriggerKeys(GroupMatcher matcher, CancellationToken cancellationToken)
+ {
+ return ExecuteInNonManagedTXLock(LockTriggerAccess, conn => GetTriggerNames(conn, matcher, cancellationToken), cancellationToken);
+ }
+
+ ///
+ /// Get the names of all of the
+ /// groups.
+ ///
+ ///
+ ///
+ /// If there are no known group names, the result should be a zero-length
+ /// array (not ).
+ ///
+ Task> IJobStore.GetJobGroupNames(CancellationToken cancellationToken)
+ {
+ return ExecuteInNonManagedTXLock(LockTriggerAccess, conn => GetJobGroupNames(conn, cancellationToken), cancellationToken);
+ }
+
+ ///
+ /// Get the names of all of the
+ /// groups.
+ ///
+ ///
+ ///
+ /// If there are no known group names, the result should be a zero-length
+ /// array (not ).
+ ///
+ Task> IJobStore.GetTriggerGroupNames(CancellationToken cancellationToken)
+ {
+ return ExecuteInNonManagedTXLock(LockTriggerAccess, conn => GetTriggerGroupNames(conn, cancellationToken), cancellationToken);
+ }
+
+ ///
+ /// Get the names of all of the s
+ /// in the .
+ ///
+ ///
+ /// If there are no Calendars in the given group name, the result should be
+ /// a zero-length array (not ).
+ ///
+ Task> IJobStore.GetCalendarNames(CancellationToken cancellationToken)
+ {
+ return ExecuteInNonManagedTXLock(LockTriggerAccess, conn => GetCalendarNames(conn, cancellationToken), cancellationToken);
+ }
+
+ ///
+ /// Get all of the Triggers that are associated to the given Job.
+ ///
+ ///
+ /// If there are no matches, a zero-length array should be returned.
+ ///
+ Task> IJobStore.GetTriggersForJob(JobKey jobKey, CancellationToken cancellationToken)
+ {
+ return ExecuteInNonManagedTXLock(LockTriggerAccess, conn => GetTriggersForJob(conn, jobKey, cancellationToken), cancellationToken);
+ }
+
+ Task> IJobStore.GetPausedTriggerGroups(CancellationToken cancellationToken)
+ {
+ return ExecuteInNonManagedTXLock(LockTriggerAccess, conn => GetPausedTriggerGroups(conn, cancellationToken), cancellationToken);
+ }
+}
diff --git a/Shoko.Server/Scheduling/ThreadPooledJobStore.cs b/Shoko.Server/Scheduling/ThreadPooledJobStore.cs
index 45bfc7561..dcd60fbb1 100644
--- a/Shoko.Server/Scheduling/ThreadPooledJobStore.cs
+++ b/Shoko.Server/Scheduling/ThreadPooledJobStore.cs
@@ -17,7 +17,7 @@
namespace Shoko.Server.Scheduling;
-public class ThreadPooledJobStore : JobStoreTX
+public partial class ThreadPooledJobStore : JobStoreTX
{
private readonly ILogger _logger;
private readonly ISettingsProvider _settingsProvider;