From 7d65885bbb39d8b9e52e0afc1b8c6e442202b24d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 17 Oct 2024 09:33:27 -0700 Subject: [PATCH] Cherry pick 51735 into release/9.4 (#52121) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add a retry mechanism to obtain the lock for inserting products through the API (#51735) * Add a retry mechanism to the query to obtain the lock for inserting products in the API * Add changefile(s) from automation for the following project(s): woocommerce * Log errors after failed attempts and delay 10ms for each attempt * Fix lint --------- Co-authored-by: github-actions * Prep for cherry pick 51735 --------- Co-authored-by: Alba Rincón Co-authored-by: github-actions Co-authored-by: WooCommerce Bot --- .../class-wc-product-data-store-cpt.php | 31 +++++++++++++++++-- plugins/woocommerce/readme.txt | 1 + 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/plugins/woocommerce/includes/data-stores/class-wc-product-data-store-cpt.php b/plugins/woocommerce/includes/data-stores/class-wc-product-data-store-cpt.php index b6da3a8e879..ec6ed431ad1 100644 --- a/plugins/woocommerce/includes/data-stores/class-wc-product-data-store-cpt.php +++ b/plugins/woocommerce/includes/data-stores/class-wc-product-data-store-cpt.php @@ -145,8 +145,35 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da return boolval( $locked ); } - // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared - $result = $wpdb->query( $query ); + // The insert query can potentially result in a deadlock if there is high concurrency + // when trying to insert products, which will result in a false negative for SKU lock + // and incorrectly products not being created. + // To mitigate this, we will retry the query 3 times before giving up. + for ( $attempts = 0; $attempts < 3; $attempts++ ) { + if ( $attempts > 1 ) { + usleep( 10000 ); + } + + // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared + $result = $wpdb->query( $query ); + if ( false !== $result ) { + break; + } + } + + if ( false === $result ) { + wc_get_logger()->warning( + sprintf( + 'Failed to obtain SKU lock for product: ID "%d" with SKU "%s" after %d attempts.', + $product_id, + $sku, + $attempts, + ), + array( + 'error' => $wpdb->last_error, + ) + ); + } return (bool) $result; } diff --git a/plugins/woocommerce/readme.txt b/plugins/woocommerce/readme.txt index a7669155ff1..66005783949 100644 --- a/plugins/woocommerce/readme.txt +++ b/plugins/woocommerce/readme.txt @@ -173,6 +173,7 @@ WooCommerce comes with some sample data you can use to see how products look; im **WooCommerce** +* Fix - Add a retry mechanism to the query to obtain the SKU lock for product creation through the API. [#51735](https://github.com/woocommerce/woocommerce/pull/51735) * Fix - Fix `Error: Failed opening required '.../wp-content/plugins/woocommerce/src/StoreApi/Schemas/V1/AI/ProductsSchema.php` fatal error [#51912](https://github.com/woocommerce/woocommerce/pull/51912) * Fix - Resolved fatal error when applying Brands-restricted coupon [#51577](https://github.com/woocommerce/woocommerce/pull/51577) * Fix - Fix CSS issue with Safari 18.0 on the product form page. [#51734](https://github.com/woocommerce/woocommerce/pull/51734)