MultiExecTransactionsWithCAS.php 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. <?php
  2. require_once 'SharedConfigurations.php';
  3. /*
  4. This is an implementation of an atomic client-side ZPOP using the support for
  5. check-and-set (CAS) operations with MULTI/EXEC transactions, as described in
  6. "WATCH explained" from http://redis.io/topics/transactions
  7. First, populate your database with a tiny sample data set:
  8. ./redis-cli
  9. SELECT 15
  10. ZADD zset 1 a
  11. ZADD zset 2 b
  12. ZADD zset 3 c
  13. */
  14. function zpop($client, $zsetKey) {
  15. $element = null;
  16. $options = array(
  17. 'cas' => true, // Initialize with support for CAS operations
  18. 'watch' => $zsetKey, // Key that needs to be WATCHed to detect changes
  19. 'retry' => 3, // Number of retries on aborted transactions, after
  20. // which the client bails out with an exception.
  21. );
  22. $txReply = $client->multiExec($options, function($tx)
  23. use ($zsetKey, &$element) {
  24. @list($element) = $tx->zrange($zsetKey, 0, 0);
  25. if (isset($element)) {
  26. $tx->multi(); // With CAS, MULTI *must* be explicitly invoked.
  27. $tx->zrem($zsetKey, $element);
  28. }
  29. });
  30. return $element;
  31. }
  32. $redis = new Predis\Client($single_server, 'dev');
  33. $zpopped = zpop($redis, 'zset');
  34. echo isset($zpopped) ? "ZPOPed $zpopped" : "Nothing to ZPOP!", "\n";
  35. ?>