1

I'm trying to generate invoice numbers that auto-increment: 2019-0001, 2019-0002, and so on.

The code works fine, but the problem arises with race conditions. If payments happen simultaneously I'm sometimes left with duplicate invoice numbers.

I've thought of just creating an auto_increment field in the database but we have a requirement that allows the user to set the starting number of the invoice. For example a user can set their invoices to start with 2019-0002 and then increment from there.

Is there a simple way to avoid duplicates?

Bonus points if the answer is compatible with WordPress as well, since the invoice numbers are custom post type titles, and I can't change the table design of posts.

jenny
  • 11
  • 1
  • What if a user sets the starting invoice to an already existing invoice? Or are invoices only unique per user? – Brett Gregson Oct 08 '19 at 09:17
  • 1
    In database you can a UNIQUE index to avoid duplicate, you can add some "lock" in your script when you add a new invoice (you create a lock file when the transaction begin for example),...just some idea – Mickaël Leger Oct 08 '19 at 09:22
  • @BrettGregson the starting invoice set by the admin won't be used if there's already an existing invoice from any user. Invoice increments uniquely for all users, not just per user. – jenny Oct 08 '19 at 11:42
  • Why are you basing an invoice system on Wordpress? Are you writing a plugin on your own? – fox91 Oct 08 '19 at 16:26
  • @fox91 yes, it's for a plugin. – jenny Oct 11 '19 at 06:55
  • @jenny WordPress isn't the right tools for that, especially if you want to save invoices as posts and the autoincrement as the title post and not a dedicated field in the table. I suggest you to choose another platform, or to write your invoice table inside the DB. – fox91 Oct 11 '19 at 07:00

1 Answers1

0

It might be worthwhile checking this out: How to set initial value and auto increment in MySQL?. You can set the auto increment starting value just by altering the table.

With regard to race conditions, in order to avoid these kinds of things, people have implemented something called 'locking', for more information on that, take a look here: https://symfony.com/doc/current/components/lock.html

Enigmatic
  • 370
  • 2
  • 11