transaction_using_cas.php 1.5KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  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 __DIR__.'/shared.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 2 b 3 c
  20. //
  21. // Then execute this script four times and see its output.
  22. //
  23. function zpop($client, $key)
  24. {
  25. $element = null;
  26. $options = array(
  27. 'cas' => true, // Initialize with support for CAS operations
  28. 'watch' => $key, // Key that needs to be WATCHed to detect changes
  29. 'retry' => 3, // Number of retries on aborted transactions, after
  30. // which the client bails out with an exception.
  31. );
  32. $client->transaction($options, function ($tx) use ($key, &$element) {
  33. @list($element) = $tx->zrange($key, 0, 0);
  34. if (isset($element)) {
  35. $tx->multi(); // With CAS, MULTI *must* be explicitly invoked.
  36. $tx->zrem($key, $element);
  37. }
  38. });
  39. return $element;
  40. }
  41. $client = new Predis\Client($single_server);
  42. $zpopped = zpop($client, 'zset');
  43. echo isset($zpopped) ? "ZPOPed $zpopped" : 'Nothing to ZPOP!', PHP_EOL;