ActionScheduler_DBStore::release_claim()publicWC 1.0

Release actions from a claim and delete the claim.

Метод класса: ActionScheduler_DBStore{}

Хуков нет.

Возвращает

null. Ничего (null).

Использование

$ActionScheduler_DBStore = new ActionScheduler_DBStore();
$ActionScheduler_DBStore->release_claim( $claim );
$claim(ActionScheduler_ActionClaim) (обязательный)
Claim object.

Код ActionScheduler_DBStore::release_claim() WC 9.3.3

public function release_claim( ActionScheduler_ActionClaim $claim ) {
	/** @var \wpdb $wpdb */
	global $wpdb;
	/**
	 * Deadlock warning: This function modifies actions to release them from claims that have been processed. Earlier, we used to it in a atomic query, i.e. we would update all actions belonging to a particular claim_id with claim_id = 0.
	 * While this was functionally correct, it would cause deadlock, since this update query will hold a lock on the claim_id_.. index on the action table.
	 * This allowed the possibility of a race condition, where the claimer query is also running at the same time, then the claimer query will also try to acquire a lock on the claim_id_.. index, and in this case if claim release query has already progressed to the point of acquiring the lock, but have not updated yet, it would cause a deadlock.
	 *
	 * We resolve this by getting all the actions_id that we want to release claim from in a separate query, and then releasing the claim on each of them. This way, our lock is acquired on the action_id index instead of the claim_id index. Note that the lock on claim_id will still be acquired, but it will only when we actually make the update, rather than when we select the actions.
	 */
	$action_ids = $wpdb->get_col( $wpdb->prepare( "SELECT action_id FROM {$wpdb->actionscheduler_actions} WHERE claim_id = %d", $claim->get_id() ) );

	$row_updates = 0;
	if ( count( $action_ids ) > 0 ) {
		$action_id_string = implode( ',', array_map( 'absint', $action_ids ) );
		$row_updates      = $wpdb->query( "UPDATE {$wpdb->actionscheduler_actions} SET claim_id = 0 WHERE action_id IN ({$action_id_string})" ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
	}

	$wpdb->delete( $wpdb->actionscheduler_claims, array( 'claim_id' => $claim->get_id() ), array( '%d' ) );

	if ( $row_updates < count( $action_ids ) ) {
		throw new RuntimeException(
			sprintf(
				// translators: %d is an id.
				__( 'Unable to release actions from claim id %d.', 'woocommerce' ),
				$claim->get_id()
			)
		);
	}
}