Redis / ServiceStack клиент Исключение транзакций - PullRequest
3 голосов
/ 21 февраля 2012

Я довольно новичок в Redis и вроде как оцениваю это. Я использую сервер Redis отсюда: https://github.com/downloads/dmajkic/redis/redis-2.4.5-win32-win64.zip

Я также использую следующую конфигурацию для сервера:

порт 6379 тайм-аут 300 сохранить 900 1 сохранить 300 10 сохранить 60 10000 loglevel debug стандартный файл журнала базы данных 1 maxclients 32 maxmemory 2147483648

Я пытаюсь запустить такой код, используя клиент ServiceStack (ServiceStack-ServiceStack.Redis-4add28a)

Вот мой код

public void InsertInsideTransaction(bool shouldTransactionRollback)
{
    RedisClient transClient = new RedisClient("localhost");

    ClearAll();
    using (var trans = transClient.CreateTransaction())
    {
        trans.QueueCommand(r => 
            {
                var redisUsers = r.GetTypedClient<User>();
                var sacha = new User { Id = redisUsers.GetNextSequence(), Name = "Sacha Barber" };
                redisUsers.Store(sacha);
                //redisUsers.Dispose();
            });

        //commit or rollback based on incoming flag
        if (shouldTransactionRollback)
            trans.Rollback();
        else
            trans.Commit();

        IList<User> users = Users();
        Console.WriteLine(string.Format("InsertInsideTransaction : There are currently {0}, Users", users.Count()));
    }




}

Где пользователь выглядит следующим образом (из одного из примеров, поставляемых с ServiceStack)

public class User
{
    public User()
    {
        this.BlogIds = new List<long>();
    }

    public long Id { get; set; }
    public string Name { get; set; }
    public List<long> BlogIds { get; set; }
}

Я получаю это исключение, когда пытаюсь совершить транзакцию

Неизвестный ответ на мульти-запрос: 43QUEUED, sPort: 60793, LastCommand: EXEC

в ServiceStack.Redis.RedisNativeClient.CreateResponseError (Строковая ошибка) в C: \ Users \ barbers \ Desktop \ Downloads \ ServiceStack-ServiceStack.Redis-4add28a \ ServiceStack-ServiceStack.Redis-4add28ed \ Red_Ru \ sistils .cs: ​​строка 146 по адресу ServiceStack.Redis.RedisNativeClient.ReadMultiDataResultCount () в C: \ Users \ barbers \ Desktop \ Downloads \ ServiceStack-ServiceStack.Redis-4add28a \ ServiceStack-ServiceStack.Redis-4add28a \ src \ ServiceSlics.SignS:. по адресу ServiceStack.Redis.Pipeline.QueuedRedisOperation.ProcessResult () в C: \ Users \ barbers \ Desktop \ Downloads \ ServiceStack-ServiceStack.Redis-4add28a \ ServiceStack-ServiceStack.Redis-4add28a \ src \ ServiceStackisued. CS: строка 169 в ServiceStack.Redis.RedisTransaction.Commit () в C: \ Users \ barbers \ Desktop \ Downloads \ ServiceStack-ServiceStack.Redis-4add28a \ ServiceStack-ServiceStack.Redis-4add28a \ src \ ServiceStack.Redis \ Transaction \ RedisTrans линия 100 в DocumentDB.Redis.RedisMessAround.InsertInsideTransaction (Boolean shouldTransactionRollback) в C: \ Users \ barbers \ Desktop \ DocumentDBs \ DocumentDB.Redis \ RedisMessAround.cs: строка 63 в DocumentDB.Redis.Program.Run () в C: \ Users \ barbers \ Desktop \ DocumentDBs \ DocumentDB.Redis \ Program.cs: строка 45 в DocumentDB.Redis.Program.Main (String [] args) в C: \ Users \ barbers \ Desktop \ DocumentDBs \ DocumentDB.Redis \ Program.cs: строка 18 в System.AppDomain._nExecuteAssembly (сборка RuntimeAssembly, аргументы String []) в System.AppDomain.ExecuteAssembly (String assemblyFile, Evidence assemblySecurity, String [] args) в Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly () в System.Threading.ThreadHelper.ThreadStart_Context (состояние объекта) в System.Threading.ExecutionContext.Run (ExecutionContext executeContext, обратный вызов ContextCallback, состояние объекта, логическое значение ignoreSyncCtx) в System.Threading.ExecutionContext.Run (ExecutionContext executeContext, обратный вызов ContextCallback, состояние объекта) в System.Threading.ThreadHelper.ThreadStart ()

Затем я подумал: «Хорошо, ребята с Redis ServiceStack работают, используя Транзакции в своих модульных тестах, поэтому я отредактировал« RedisTransactionTests », которые пришли с клиентом ServiceStack (ServiceStack-ServiceStack.Redis-4add28a), который я использую

Вот что я добавил в «RedisTransactionTests»

public class User
{
    public User()
    {
        this.BlogIds = new List<long>();
    }

    public long Id { get; set; }
    public string Name { get; set; }
    public List<long> BlogIds { get; set; }
}

где у меня есть этот отредактированный тестовый код

[Test]
[TestCase(true)]
[TestCase(false)]
public void TestUserTrans(bool shouldTransactionRollback)
{
    int count = 0;


    IRedisTransaction trans = Redis.CreateTransaction();

    try
    {
        trans.QueueCommand(r =>
        {
            var redisUsers = r.GetTypedClient<User>();
            var sacha = new User { Id = redisUsers.GetNextSequence(), Name = "Sacha Barber" };
            redisUsers.Store(sacha);
        });

        //commit or rollback based on incoming flag
        if (shouldTransactionRollback)
            trans.Rollback();
        else
            trans.Commit();
    }
    catch (Exception ex)
    {

    }

    IList<User> users = Users();
    count = users.Count();
    Console.WriteLine(string.Format("TestUserTrans : There are currently {0}, Users", users.Count()));
    if (shouldTransactionRollback)
        Assert.That(count == 0);
    else
        Assert.That(count == 1);

}

Там исключение кажется полностью проглоченным.

Что, черт возьми, я делаю не так

1 Ответ

4 голосов
/ 21 февраля 2012

Вы не можете читать и использовать результаты в одних и тех же транзакциях.

Обязательно прочитайте, как работает MULTI / EXEC: http://redis.io/topics/transactions

Он эффективно работает путем объединения нескольких команд в одну составную команду, которая отправляется и обрабатывается Redis за один раз.

В вашем примере вы пытаетесь выполнить чтение с redisUsers.GetNextSequence() и использовать результат из транзакции в очереди. Вы не можете сделать это, вместо этого, если вы хотите использовать переменные в своих транзакциях, поставленных в очередь, вам нужно прочитать их раньше:

var sacha = new User { 
    Id = Redis.As<User>().GetNextSequence(), Name = "Sacha Barber" };

trans.QueueCommand(r =>  r.As<User>().Store(sacha));

Примечание: .As<T>() является сокращением для r.GetTypedClient<T>()

Для обеспечения целостности транзакции при чтении вы можете выполнить команду WATCH , чтобы указать все переменные, которые будет использовать ваша транзакция. Затем, если какая-либо из этих переменных будет изменена до завершения транзакции, будет сгенерировано исключение, и ни одна из операций в очереди не будет выполнена.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...