User: Bypass repeatable-read when creating an actor_id
authorBrad Jorsch <bjorsch@wikimedia.org>
Thu, 29 Nov 2018 14:03:20 +0000 (09:03 -0500)
committerBrad Jorsch <bjorsch@wikimedia.org>
Thu, 29 Nov 2018 16:28:05 +0000 (11:28 -0500)
commit37f48fdb25a78ba7623c57b50cdfd842292d3ccb
tree66be7b0bd3e92ec042c140d2e4ed9f4192b9b059
parent6e58bfb43a161235444d10d8cf42e8f0eaee4efe
User: Bypass repeatable-read when creating an actor_id

When MySQL is using repeatable-read transaction isolation (which is the
default), the following sequence of events can occur:

1. Request A: Begin a transaction.
2. Request A: Try to select the actor ID for a user. Find no rows.
3. Request B: Insert an actor ID for that user.
4. Request A: Try to insert an actor ID for the user. Fails because one
   exists.
5. Request A: Try to select the actor ID that must exist. Fail because of
   the snapshot created at step 2.

In MySQL we can avoid this issue at step #5 by using a locking select
(FOR UPDATE or LOCK IN SHARE MODE), so let's do that.

Bug: T210621
Change-Id: I6c1d255fdd14c6f49d2ea9790e7bd7d101e98ee4
includes/user/User.php