Redis specifically has the "NX option" which sets a lock value ONLY if the value is presently empty to handle this situation (see http://redis.io/topics/distlock), so I believe that is the proper solution instead of a transaction lock.
I have attached a patch to the raw 3.70 source with a new WebFarmTaskRaceCondition unit test which will reproduce this behavior. This test explicitly forces Tasks running on two different threads to enter the lock simultaneously. You can see both of them run concurrently and print
Executing TaskRace on Thread 10....
Executing TaskRace on Thread 11....
in the output.
Patch at https://gist.github.com/anonymous/f783a4793f039f46ef3b/raw/489779eeb07d0d1efd88a57de80ed72f9af593e8/race_condition_repro.patch
To apply the patch
1. From the downloaded 3.70 source:
~/Downloads/nopcommerce370/nopCommerce_3.70_Source$ patch -p2 -l < race-condition-repro.patch
2. From git:
git checkout f6b7de7 # checkout the 3.70 release
git checkout -b race-condition-repro
git apply < race-condition-repro.patch
Thanks,
Matt