Nevermind, I see what you mean.
So you want a lock on the entity once you know it exists (and satisfies your where clause).
..since something might have come along and updated the p1 column from None to Something before your transaction began.. and thus the key would refer to an entity that does not satisfy your where clause anymore.
If you were willing to let whoever got to it first to update the p1 column.. you could have your transaction verify that p1 was still None once it got the entity inside of the transaction.
If p1 had changed.. then just do nothing since another transaction already won the race.
I think that would work just the same. Because, assume you have two processes looking for an entity where p1 = None and p2 = Today.. and they each really, really want to update p1 to some value.
One of the processes must win in your scenario.. you just don't want the other one to re-update the entity since it has already been updated.. and p1 <> None. Now, you still need the transaction of course.. but just add a check after grabbing the entity to verify that p1 = None before doing any updates.