TransactionWithCAS.php 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. <?php
  2. /*
  3. * This file is part of the Predis package.
  4. *
  5. * (c) Daniele Alessandri <suppakilla@gmail.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. require 'SharedConfigurations.php';
  11. // This is an implementation of an atomic client-side ZPOP using the support for
  12. // check-and-set (CAS) operations with MULTI/EXEC transactions, as described in
  13. // "WATCH explained" from http://redis.io/topics/transactions
  14. //
  15. // First, populate your database with a tiny sample data set:
  16. //
  17. // ./redis-cli
  18. // SELECT 15
  19. // ZADD zset 1 a
  20. // ZADD zset 2 b
  21. // ZADD zset 3 c
  22. //
  23. // Then execute this script four times and see its output.
  24. //
  25. function zpop($client, $key)
  26. {
  27. $element = null;
  28. $options = array(
  29. 'cas' => true, // Initialize with support for CAS operations
  30. 'watch' => $key, // Key that needs to be WATCHed to detect changes
  31. 'retry' => 3, // Number of retries on aborted transactions, after
  32. // which the client bails out with an exception.
  33. );
  34. $client->transaction($options, function ($tx) use ($key, &$element) {
  35. @list($element) = $tx->zrange($key, 0, 0);
  36. if (isset($element)) {
  37. $tx->multi(); // With CAS, MULTI *must* be explicitly invoked.
  38. $tx->zrem($key, $element);
  39. }
  40. });
  41. return $element;
  42. }
  43. $client = new Predis\Client($single_server);
  44. $zpopped = zpop($client, 'zset');
  45. echo isset($zpopped) ? "ZPOPed $zpopped" : "Nothing to ZPOP!", PHP_EOL;