sql >> Database teknologi >  >> NoSQL >> Redis

Redis-transaktioner

Denne side giver eksempler på, hvordan man opretter atomiske Redis-transaktioner med ServiceStackRedis Service Stacks C# Redis Client

Sådan opretter du tilpassede atomoperationer i Redis #

Et af hovedtræk ved Redis er evnen til at konstruere brugerdefinerede atomoperationer. Dette opnås ved at bruge Redis's MULTI/EXEC/DISCARD operationer.

ServiceStacks C# Redis-klient gør det nemt at bruge Redis-transaktioner ved at levere en stærkt indtastet IRedisTransaction (for strenge) og IRedisTypedTransaction (for POCO-typer) API'er med bekvemmelighedsmetoder, så du kan kombinere enhver IRedisClient-operation inden for en enkelt transaktion.

Oprettelse af en transaktion udføres ved at kalde IRedisClient.CreateTransaction() . Derfra 'sætter du i kø' alle operationer, som du ønsker skal være en del af transaktionen ved at bruge en af ​​IRedisTransaction.QueueCommand() overbelastninger. Derefter kan du udføre alle operationerne ved at kalde IRedisTransaction.Commit() som vil sende 'EXEC'-kommandoen til Redis-serveren, der udfører alle kommandoerne i kø og behandler deres tilbagekald.

Hvis du ikke kalder Commit() før slutningen af ​​brugsblokken, Dispose() metoden vil automatisk kalde Rollback() som vil sende 'DISCARD'-kommandoen, der fjerner den aktuelle transaktion og nulstiller Redis-klientforbindelsen tilbage til dens tidligere tilstand.

Eksempler på Redis-transaktioner #

Nedenfor er et simpelt eksempel, der viser, hvordan man sætter Redis-operationer i kø med og uden tilbagekald.

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'.

Andre almindelige eksempler #

Den fulde kildekode og andre almindelige eksempler kan findes på siden med almindelige transaktionstests.

[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" }));
}

Alt-i-et eksempel #

Dette og andre eksempler kan findes ved at se på RedisTransactionTests.cs testsuite.

Her er et alt-i-et-eksempel, der kombinerer forskellige Redis-operationer inden for en enkelt transaktion:

[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. MongoDB $setDifference

  2. Python-redis:Hent binære data efter en klient blev sat op med decode_responses=True

  3. Sådan fortæller du en klient, hvor den nye Redis-master bruger Sentinel

  4. Find en streng i en streng i SQL