Redis
 sql >> Baza danych >  >> NoSQL >> Redis

Transakcje Redis

Ta strona zawiera przykłady tworzenia atomowych transakcji Redis za pomocą klienta C# Redis ServiceStackRedis Service Stack

Jak tworzyć niestandardowe atomowe operacje w Redis #

Jedną z głównych cech Redis jest możliwość konstruowania niestandardowych operacji atomowych. Osiąga się to dzięki wykorzystaniu operacji MULTI/EXEC/DISCARD w Redis.

Usługa ServiceStack C# Redis Client ułatwia korzystanie z transakcji Redis, zapewniając interfejsy API IRedisTransaction (dla ciągów) i IRedisTypedTransaction (dla typów POCO) o silnym typie z wygodnymi metodami, które umożliwiają łączenie dowolnej operacji IRedisClient w ramach jednej transakcji.

Tworzenie transakcji odbywa się poprzez wywołanie IRedisClient.CreateTransaction() . Stamtąd „Kolejkujesz” wszystkie operacje, które chcesz być częścią transakcji, używając jednej z IRedisTransaction.QueueCommand() przeciążenia. Następnie możesz wykonać wszystkie operacje, wywołując IRedisTransaction.Commit() który wyśle ​​polecenie „EXEC” do serwera Redis, wykonując wszystkie polecenia w kolejce i przetwarzając ich wywołania zwrotne.

Jeśli nie wywołasz funkcji Commit() przed końcem bloku using, Dispose() metoda automatycznie wywoła Rollback() który wyśle ​​polecenie „DISCARD” usuwające bieżącą transakcję i resetujące połączenie klienta Redis z powrotem do poprzedniego stanu.

Przykłady transakcji Redis #

Poniżej znajduje się prosty przykład pokazujący, jak kolejkować operacje Redis z wywołaniem zwrotnym i bez niego.

int callbackResult;
using (var trans = redis.CreateTransaction())
{
  trans.QueueCommand(r => r.Increment("key"));  
  trans.QueueCommand(r => r.Increment("key"), i => callbackResult = i);  

  trans.Commit();
}
//The value of "key" is incremented twice. The latest value of which is also stored in 'callbackResult'.

Inne typowe przykłady #

Pełny kod źródłowy i inne typowe przykłady można znaleźć na stronie z popularnymi testami transakcji.

[Test]
public void Can_Set_and_Expire_key_in_atomic_transaction()
{
    var oneSec = TimeSpan.FromSeconds(1);

    Assert.That(Redis.GetString("key"), Is.Null);
    using (var trans = Redis.CreateTransaction())                  //Calls 'MULTI'
    {
        trans.QueueCommand(r => r.SetString("key", "a"));      //Queues 'SET key a'
        trans.QueueCommand(r => r.ExpireKeyIn("key", oneSec)); //Queues 'EXPIRE key 1'

        trans.Commit();                                        //Calls 'EXEC'

    }                                                              //Calls 'DISCARD' if 'EXEC' wasn't called

    Assert.That(Redis.GetString("key"), Is.EqualTo("a"));
    Thread.Sleep(TimeSpan.FromSeconds(2));
    Assert.That(Redis.GetString("key"), Is.Null);
}

[Test]
public void Can_Pop_priority_message_from_SortedSet_and_Add_to_workq_in_atomic_transaction()
{
    var messages = new List<string> { "message4", "message3", "message2" };

    Redis.AddToList("workq", "message1");

    var priority = 1;
    messages.ForEach(x => Redis.AddToSortedSet("prioritymsgs", x, priority++));

    var highestPriorityMessage = Redis.PopFromSortedSetItemWithHighestScore("prioritymsgs");

    using (var trans = Redis.CreateTransaction())
    {
        trans.QueueCommand(r => r.RemoveFromSortedSet("prioritymsgs", highestPriorityMessage));
        trans.QueueCommand(r => r.AddToList("workq", highestPriorityMessage));	

        trans.Commit();											
    }

    Assert.That(Redis.GetAllFromList("workq"), 
        Is.EquivalentTo(new List<string> { "message1", "message2" }));
    Assert.That(Redis.GetAllFromSortedSet("prioritymsgs"), 
        Is.EquivalentTo(new List<string> { "message3", "message4" }));
}

Przykład-wszystko-w-jednym #

Ten i inne przykłady można znaleźć w zestawie testów RedisTransactionTests.cs.

Oto kompleksowe przykłady łączące różne operacje Redis w ramach jednej transakcji:

[Test]
public void Supports_different_operation_types_in_same_transaction()
{
    var incrementResults = new List<int>();
    var collectionCounts = new List<int>();
    var containsItem = false;

    Assert.That(Redis.GetString(Key), Is.Null);
    using (var trans = Redis.CreateTransaction())
    {
        trans.QueueCommand(r => r.Increment(Key), intResult => incrementResults.Add(intResult));
        trans.QueueCommand(r => r.AddToList(ListKey, "listitem1"));
        trans.QueueCommand(r => r.AddToList(ListKey, "listitem2"));
        trans.QueueCommand(r => r.AddToSet(SetKey, "setitem"));
        trans.QueueCommand(r => r.SetContainsValue(SetKey, "setitem"), b => containsItem = b);
        trans.QueueCommand(r => r.AddToSortedSet(SortedSetKey, "sortedsetitem1"));
        trans.QueueCommand(r => r.AddToSortedSet(SortedSetKey, "sortedsetitem2"));
        trans.QueueCommand(r => r.AddToSortedSet(SortedSetKey, "sortedsetitem3"));
        trans.QueueCommand(r => r.GetListCount(ListKey), intResult => collectionCounts.Add(intResult));
        trans.QueueCommand(r => r.GetSetCount(SetKey), intResult => collectionCounts.Add(intResult));
        trans.QueueCommand(r => r.GetSortedSetCount(SortedSetKey), intResult => collectionCounts.Add(intResult));
        trans.QueueCommand(r => r.Increment(Key), intResult => incrementResults.Add(intResult));

        trans.Commit();
    }

    Assert.That(containsItem, Is.True);
    Assert.That(Redis.GetString(Key), Is.EqualTo("2"));
    Assert.That(incrementResults, Is.EquivalentTo(new List<int> { 1, 2 }));
    Assert.That(collectionCounts, Is.EquivalentTo(new List<int> { 2, 1, 3 }));
    Assert.That(Redis.GetAllFromList(ListKey), Is.EquivalentTo(new List<string> { "listitem1", "listitem2" }));
    Assert.That(Redis.GetAllFromSet(SetKey), Is.EquivalentTo(new List<string> { "setitem" }));
    Assert.That(Redis.GetAllFromSortedSet(SortedSetKey), Is.EquivalentTo(new List<string> { "sortedsetitem1", "sortedsetitem2", "sortedsetitem3" }));
}

  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Memcached kontra Redis?

  2. Czy możliwe jest posiadanie pamięci podręcznej Linux VFS z systemem plików FUSE?

  3. wyślij wiadomość downstream do google ccs z węzłem js

  4. Utrzymuj przy życiu dane Redis między docker-compose w dół i w górę w kontenerze Docker

  5. Django, Redis:Gdzie umieścić kod połączenia