An astute reader pointed out that there is a transactional integrity problem with the HAppS application built over the last 4 posts. The function checkAndAdd in Finished HAppS Application contains a call to "query $ IsUser" as well as a call to "update $ AddUser". This violates that ACID guarantee that was desired from the checkAndAdd function. If two people simultaneously try to create the same username, it's possible that both of them could get past the "query" and "if exists" statements before either of the "update AddUser" statements are executed. In this case, both of the AddUser updates would succeed and both users would think their account was created. But if they had the same username, then first one would be overwritten by the second one. The second user wouldn't notice a problem, but the first user would not be able to log in to the newly created account because his password would probably be different from the password chosen by the second user. This wouldn't be the end of the world, but it would certainly create frustration for the first user.

The problem exists because HAppS gives us transactional guarantees at the query and update level only. I just didn't think about it when I originally wrote the code. I could just give the fix, but I'll outline incorrect attempts I made before I got to the fix. Hopefully it will be more beneficial to see some wrong solutions and how they got corrected. Since I'm still trying to overcome tendencies learned from years of imperative programming, maybe this will be useful to other people in the same position. First we need to modify the addUser function to check for the existence of the user first. What we want is something like the following: