• Skip to primary navigation
  • Skip to main content
  • Skip to footer
Essential Premium WooCommerce Plugins - WP Desk
  • Plugins
  • Bundle
  • Support
  • Blog
  • My Account
  • 0

Stay updated on our how-to articles

WP Desk news, WooCommerce tips, promo codes - right to your inbox.

By entering your e-mail, you agree to our Terms & Conditions and Privacy Policy.

Krzysiek Dyszczyk

Atomic operations in WordPress

Updated: March 05, 2021 / Tech Posts

As the famous saying goes, There are only two hard things in Computer Science: cache invalidation and naming things. The author of this saying has apparently never run into any problems with process synchronization.

Threads... Threads everywhere

It's easy to forget that although we usually don't write asynchronous code in PHP and the WordPress backend, each line of code executes sequentially; in practice, the server runs and executes multiple PHP processes simultaneously. For this reason,every plugin’s code is always executed concurrently. We must always bear in mind the problems that arise in multi-threaded and distributed environments.

A typical WordPress problem where multithreading rears its ugly head is when, based on the value of a variable stored in the database, we set a new value for this variable. Strangely enough, such situations happen very often.

Snake in the grass

Let's assume that, as in WooCommerce, there is a post_type named product, and its metadata store information about how many products are in stock. When a customer buys a product, we want to reduce the number of products in stock by one. How to do it? Nothing is easier: we read the number of products in stock, decrease the value by one, and save it back.

Trivial? Yes, as long as we do not receive a report from the first angry customer who has sold more products than they had in stock. The next customer reports that they still have products in stock, but the store says there are no more. What has happened? Has anyone hacked our WordPress to put random numbers into the database? Or maybe it's because we haven’t used WooCommerce methods? Let's try:

Now it's PRO. We can now go to sleep, sure that this time we did everything perfectly. Unfortunately, the morning will bring us another sad customer. What happened? How could we have made a fatal error in two lines of otherwise obviously correct code?

But why doesn't it work

As you might have guessed, the problem is that multiple PHP processes can modify the same information simultaneously. Imagine that two different customers purchase the same product at the same time. Both processes take place parallelly. The first process gets the number of products in stock, the second process also does it a millisecond later; both get the same value, say 9. Both processes decrease this value by 1 and get 8, and both write the number 8 to the database. We sold two products, but the shop thinks there are still 8 products in stock. If no one notices this, products that are not in stock will soon be purchased.

While one PHP process was calmly executing line-by-line commands, another process slipped into the same place in the code and mixed up everything.
Will this happen frequently, or is it a purely academic problem? Unfortunately, and counterintuitively, since threads tend to wait together for I/O operations, this type of code will often fail even in a small store. It's just a matter of time.

How to solve this problem?

Atomic operation

Often, and this is also the case here, it is possible to replace several operations with one atomic operation. An atomic operation cannot be subdivided into smaller ones. Such an operation is either done or not done and will never be done a little. Because when we do the work with an atomic operation, other PHP processes will not enter between our commands. With one command, we will simultaneously get, change, and save the warehouse's stock. How to do it?
Certainly NOT like this:

Such refactoring does not change anything. PHP processes will continue to enter and execute the decrease_stock function line by line. The fact that a function can be invoked with one PHP command does not make the operation atomic.

Database to the rescue

We can take advantage of the database and the fact that a single UPDATE/DELETE operation is always atomic.

Now we have a code that will reduce the number of products in stock with one atomic operation.Note that we cannot use the wpdb::update method because this command does not enable decreasing the value, only overwriting it.

What to do when the task cannot be easily reduced to a single atomic operation? How does a database handle reading, changing, and writing values ​​atomically? I will share this with you in the next posts!

Tweet

3 minutes read2085 views

Krzysiek Dyszczyk

Co-founder of WP Desk. Responsible for the coordination of technical topics. Fosters programmers' growth and happiness so that their code remains funky-fresh.

Powered by WP Desk

WP Desk brings you great WooCommerce plugins. We strive to save your time and money by speeding up your processes. Use our plugins to build a better store. Awesome support included in the package.

Premium WooCommerce Plugins →

Stay updated on our how-to articles

WP Desk news, WooCommerce tips, promo codes - right to your inbox.

By entering your e-mail, you agree to our Terms & Conditions and Privacy Policy.

WP Desk › Tech Posts › Atomic operations in WordPress

Footer

WP Desk - WooCommerce Plugins

At WP Desk we create great WooCommerce plugins with awesome support. Save time and money with our e-commerce solutions. See how we can help you improve your e-store →

Secured by Comodo

WP Desk

  • About us
  • Giving Back
  • Blog
  • Contact us

Products

  • Premium Plugins
  • Get Support
  • WooCommerce Invoices
  • Email Marketing
  • Octolize

Legal

  • Terms & Conditions
  • Refund Policy
  • Support Policy
  • Privacy Policy

© 2023 WP Desk