Redis
 sql >> база данни >  >> NoSQL >> Redis

Транзакции на Redis

Тази страница предоставя примери за това как да създавате атомарни транзакции Redis с C# Redis клиента на ServiceStackRedis Service Stack

Как да създадете персонализирани атомни операции в Redis #

Една от основните характеристики на Redis е способността да се конструират персонализирани атомни операции. Това се постига чрез използване на операциите MULTI/EXEC/DISCARD на Redis.

C# Redis Client на ServiceStack улеснява използването на Redis транзакции, като предоставя строго типизирани IRedisTransaction (за низове) и IRedisTypedTransaction (за типове POCO) с удобни методи, които ви позволяват да комбинирате всяка операция IRedisClient в рамките на една транзакция.

Създаването на транзакция се извършва чрез извикване на IRedisClient.CreateTransaction() . Оттам вие "подреждате" в опашка всички операции, които искате да бъдат част от транзакцията, като използвате един от IRedisTransaction.QueueCommand() претоварвания. След това можете да изпълните всички операции, като извикате IRedisTransaction.Commit() което ще изпрати командата 'EXEC' до сървъра на Redis, изпълнявайки всички команди в опашката и обработвайки техните обратни извиквания.

Ако не извикате Commit() преди края на блока using, Dispose() метод автоматично ще извика Rollback() това ще изпрати командата 'DISCARD' за премахване на текущата транзакция и нулиране на клиентската връзка на Redis обратно към предишното й състояние.

Примери за транзакции на Redis #

По-долу е даден прост пример, показващ как да поставите в опашка операции на Redis със и без обратно извикване.

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

Други често срещани примери #

Пълният изходен код и други често срещани примери могат да бъдат намерени на страницата за общи тестове за транзакции.

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

Пример за всичко в едно #

Този и други примери можете да намерите, като разгледате тестовия пакет RedisTransactionTests.cs.

Ето примери всичко в едно, комбиниращи различни операции на Redis в рамките на една транзакция:

[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. Redis и Memcache или просто Redis?

  2. Как да създадете Redis връзка с Master и Slave

  3. Кой е най-ефективният във времето начин за сериализиране/десериализиране на DataTable към/от Redis?

  4. Каква е най-добрата стратегия за синхронизиране на Redis данни с MySQL?

  5. Разлики между Microsoft.Extensions.Cashing.Redis и Microsoft.Extensions.Caching.StackExchangeRedis.RedisCache