April 2019 Archives

Atomic Updates with DBIx::Class

As we're building Tau Station, a narrative sci-fi MMORPG written in Perl, we've encountered any of a number of challenges, not the least of which is that this is a very "write-heavy" application. Further, because it's a universe where people interact, there's often no clear isolation between what you can change and what I can change. Thus, there's a lot of writing to the database and often to the same data!

By now you've probably heard of the Object-Relational Impedance Mismatch, which is just a fancy way of saying "collections of objects and databases aren't the same thing."

One problem which is particularly difficult is handling "syndicate credits". Syndicates ("guilds" in other MMORPGs) can tax their members and every time a member gets credits deposited in their bank account, a certain percentage goes to the syndicate. So let's say two syndicate members each earn 100 credits at the same time, paying 10% tax to their syndicates. It can look like this:

  • Process #1: Read how many credits a given syndicate has.
  • Process #2: Read how many credits a syndicate has.
  • Process #1: Set syndicate credits = credits + 10
  • Process #2: Set syndicate credits = credits + 10

Logically, the syndicate should end up with an extra 20 credits. But if you do a naïve:

$syndicate->update({ credits => $credits + $tax });

... you can easily wind up with 10 credits because the "Process #2" read the total credits before "Process #1" wrote them out. Fortunately, there's an easy fix to this.

About Ovid

user-pic Freelance Perl/Testing/Agile consultant and trainer. See http://www.allaroundtheworld.fr/ for our services. If you have a problem with Perl, we will solve it for you. And don't forget to buy my book! http://www.amazon.com/Beginning-Perl-Curtis-Poe/dp/1118013840/