Merge pull request #20537 from woocommerce/update/transactions-revert

Transactions, caching, and version transient cleanup issues
This commit is contained in:
Claudiu Lodromanean 2018-06-15 09:11:23 -07:00 committed by GitHub
commit ee47ceb361
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 32 additions and 38 deletions

View File

@ -360,8 +360,6 @@ class WC_API_Orders extends WC_API_Resource {
public function create_order( $data ) {
global $wpdb;
wc_transaction_query( 'start' );
try {
if ( ! isset( $data['order'] ) ) {
throw new WC_API_Exception( 'woocommerce_api_missing_order_data', sprintf( __( 'No %1$s data specified to create %1$s', 'woocommerce' ), 'order' ), 400 );
@ -466,15 +464,10 @@ class WC_API_Orders extends WC_API_Resource {
do_action( 'woocommerce_api_create_order', $order->get_id(), $data, $this );
do_action( 'woocommerce_new_order', $order->get_id() );
wc_transaction_query( 'commit' );
return $this->get_order( $order->get_id() );
} catch ( WC_Data_Exception $e ) {
wc_transaction_query( 'rollback' );
return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => 400 ) );
} catch ( WC_API_Exception $e ) {
wc_transaction_query( 'rollback' );
return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) );
}
}

View File

@ -389,16 +389,12 @@ class WC_API_Orders extends WC_API_Resource {
* Create an order
*
* @since 2.2
*
* @param array $data raw order data
*
* @return array|WP_Error
*/
public function create_order( $data ) {
global $wpdb;
wc_transaction_query( 'start' );
try {
if ( ! isset( $data['order'] ) ) {
throw new WC_API_Exception( 'woocommerce_api_missing_order_data', sprintf( __( 'No %1$s data specified to create %1$s', 'woocommerce' ), 'order' ), 400 );
@ -508,15 +504,10 @@ class WC_API_Orders extends WC_API_Resource {
do_action( 'woocommerce_api_create_order', $order->get_id(), $data, $this );
do_action( 'woocommerce_new_order', $order->get_id() );
wc_transaction_query( 'commit' );
return $this->get_order( $order->get_id() );
} catch ( WC_Data_Exception $e ) {
wc_transaction_query( 'rollback' );
return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => 400 ) );
} catch ( WC_API_Exception $e ) {
wc_transaction_query( 'rollback' );
return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) );
}
}

View File

@ -134,17 +134,35 @@ class WC_Cache_Helper {
public static function get_transient_version( $group, $refresh = false ) {
$transient_name = $group . '-transient-version';
$transient_value = get_transient( $transient_name );
$transient_value = strval( $transient_value ? $transient_value : '' );
if ( false === $transient_value || true === $refresh ) {
self::delete_version_transients( $transient_value );
if ( '' === $transient_value || true === $refresh ) {
$old_transient_value = $transient_value;
$transient_value = (string) time();
$transient_value = time();
if ( $old_transient_value === $transient_value ) {
// Time did not change but transient needs flushing now.
self::delete_version_transients( $transient_value );
} else {
self::queue_delete_version_transients( $transient_value );
}
set_transient( $transient_name, $transient_value );
}
return $transient_value;
}
/**
* Queues a cleanup event for version transients.
*
* @param string $version Version of the transient to remove.
*/
protected static function queue_delete_version_transients( $version = '' ) {
if ( ! wp_using_ext_object_cache() && ! empty( $version ) ) {
wp_schedule_single_event( time() + 30, 'delete_version_transients', array( $version ) );
}
}
/**
* When the transient version increases, this is used to remove all past transients to avoid filling the DB.
*
@ -165,9 +183,9 @@ class WC_Cache_Helper {
$affected = $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->options} WHERE option_name LIKE %s ORDER BY option_id LIMIT %d;", '\_transient\_%' . $version, $limit ) ); // WPCS: cache ok, db call ok.
// If affected rows is equal to limit, there are more rows to delete. Delete in 10 secs.
// If affected rows is equal to limit, there are more rows to delete. Delete in 30 secs.
if ( $affected === $limit ) {
wp_schedule_single_event( time() + 10, 'delete_version_transients', array( $version ) );
self::queue_delete_version_transients( $version );
}
}
}

View File

@ -102,8 +102,6 @@ class WC_Order extends WC_Abstract_Order {
}
try {
wc_transaction_query( 'start' );
do_action( 'woocommerce_pre_payment_complete', $this->get_id() );
if ( WC()->session ) {
@ -124,20 +122,18 @@ class WC_Order extends WC_Abstract_Order {
} else {
do_action( 'woocommerce_payment_complete_order_status_' . $this->get_status(), $this->get_id() );
}
wc_transaction_query( 'commit' );
} catch ( Exception $e ) {
wc_transaction_query( 'rollback' );
/**
* If there was an error completing the payment, log to a file and add an order note so the admin can take action.
*/
$logger = wc_get_logger();
$logger->error(
sprintf( 'Payment complete of order #%d failed!', $this->get_id() ), array(
sprintf( 'Error completing payment for order #%d', $this->get_id() ), array(
'order' => $this,
'error' => $e,
)
);
$this->add_order_note( __( 'Payment complete event failed.', 'woocommerce' ) . ' ' . $e->getMessage() );
return false;
}
return true;
@ -320,18 +316,12 @@ class WC_Order extends WC_Abstract_Order {
}
try {
wc_transaction_query( 'start' );
$this->set_status( $new_status, $note, $manual );
$this->save();
wc_transaction_query( 'commit' );
} catch ( Exception $e ) {
wc_transaction_query( 'rollback' );
$logger = wc_get_logger();
$logger->error(
sprintf( 'Update status of order #%d failed!', $this->get_id() ), array(
sprintf( 'Error updating status for order #%d', $this->get_id() ), array(
'order' => $this,
'error' => $e,
)

View File

@ -324,7 +324,7 @@ abstract class Abstract_WC_Order_Data_Store_CPT extends WC_Data_Store_WP impleme
global $wpdb;
// Get from cache if available.
$items = wp_cache_get( 'order-items-' . $order->get_id(), 'orders' );
$items = 0 < $order->get_id() ? wp_cache_get( 'order-items-' . $order->get_id(), 'orders' ) : false;
if ( false === $items ) {
$items = $wpdb->get_results(
@ -333,7 +333,9 @@ abstract class Abstract_WC_Order_Data_Store_CPT extends WC_Data_Store_WP impleme
foreach ( $items as $item ) {
wp_cache_set( 'item-' . $item->order_item_id, $item, 'order-items' );
}
wp_cache_set( 'order-items-' . $order->get_id(), $items, 'orders' );
if ( 0 < $order->get_id() ) {
wp_cache_set( 'order-items-' . $order->get_id(), $items, 'orders' );
}
}
$items = wp_list_filter( $items, array( 'order_item_type' => $type ) );