@@ -56,6 +56,11 @@ class Schedule extends \Magento\Framework\Model\AbstractModel
5656 */
5757 private $ dateTimeFactory ;
5858
59+ /**
60+ * @var DeadlockRetrierInterface
61+ */
62+ private $ retrier ;
63+
5964 /**
6065 * @param \Magento\Framework\Model\Context $context
6166 * @param \Magento\Framework\Registry $registry
@@ -64,6 +69,7 @@ class Schedule extends \Magento\Framework\Model\AbstractModel
6469 * @param array $data
6570 * @param TimezoneInterface|null $timezoneConverter
6671 * @param DateTimeFactory|null $dateTimeFactory
72+ * @param DeadlockRetrierInterface $retrier
6773 */
6874 public function __construct (
6975 \Magento \Framework \Model \Context $ context ,
@@ -72,11 +78,13 @@ public function __construct(
7278 \Magento \Framework \Data \Collection \AbstractDb $ resourceCollection = null ,
7379 array $ data = [],
7480 TimezoneInterface $ timezoneConverter = null ,
75- DateTimeFactory $ dateTimeFactory = null
81+ DateTimeFactory $ dateTimeFactory = null ,
82+ DeadlockRetrierInterface $ retrier = null
7683 ) {
7784 parent ::__construct ($ context , $ registry , $ resource , $ resourceCollection , $ data );
7885 $ this ->timezoneConverter = $ timezoneConverter ?: ObjectManager::getInstance ()->get (TimezoneInterface::class);
7986 $ this ->dateTimeFactory = $ dateTimeFactory ?: ObjectManager::getInstance ()->get (DateTimeFactory::class);
87+ $ this ->retrier = $ retrier ?: ObjectManager::getInstance ()->get (DeadlockRetrierInterface::class);
8088 }
8189
8290 /**
@@ -251,21 +259,42 @@ public function getNumeric($value)
251259 }
252260
253261 /**
254- * Lock the cron job so no other scheduled instances run simultaneously .
262+ * Sets a job to STATUS_RUNNING only if it is currently in STATUS_PENDING .
255263 *
256- * Sets a job to STATUS_RUNNING only if it is currently in STATUS_PENDING
257- * and no other jobs of the same code are currently in STATUS_RUNNING.
258264 * Returns true if status was changed and false otherwise.
259265 *
260266 * @return boolean
261267 */
262268 public function tryLockJob ()
263269 {
264- if ($ this ->_getResource ()->trySetJobUniqueStatusAtomic (
265- $ this ->getId (),
266- self ::STATUS_RUNNING ,
267- self ::STATUS_PENDING
268- )) {
270+ /** @var \Magento\Cron\Model\ResourceModel\Schedule $scheduleResource */
271+ $ scheduleResource = $ this ->_getResource ();
272+
273+ // Change statuses from running to error for terminated jobs
274+ $ this ->retrier ->execute (
275+ function () use ($ scheduleResource ) {
276+ return $ scheduleResource ->getConnection ()->update (
277+ $ scheduleResource ->getTable ('cron_schedule ' ),
278+ ['status ' => self ::STATUS_ERROR ],
279+ ['job_code = ? ' => $ this ->getJobCode (), 'status = ? ' => self ::STATUS_RUNNING ]
280+ );
281+ },
282+ $ scheduleResource ->getConnection ()
283+ );
284+
285+ // Change status from pending to running for ran jobs
286+ $ result = $ this ->retrier ->execute (
287+ function () use ($ scheduleResource ) {
288+ return $ scheduleResource ->trySetJobStatusAtomic (
289+ $ this ->getId (),
290+ self ::STATUS_RUNNING ,
291+ self ::STATUS_PENDING
292+ );
293+ },
294+ $ scheduleResource ->getConnection ()
295+ );
296+
297+ if ($ result ) {
269298 $ this ->setStatus (self ::STATUS_RUNNING );
270299 return true ;
271300 }
0 commit comments