Redis / ServiceStack客户端事务异常

时间:2012-02-21 15:14:01

标签: redis

我是Redis的新手,我正在评估它。我从这里使用Redis服务器:https://github.com/downloads/dmajkic/redis/redis-2.4.5-win32-win64.zip

我也在服务器上使用以下配置:

端口6379 超时300 节省900 1 节省300 10 节省60 10000 loglevel调试 logfile标准输出 数据库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

在C:\ Users \ barbers \ Desktop \ Downloads \ ServiceStack-ServiceStack.Redis-4add28a \ ServiceStack-ServiceStack.Redis-4add28a \ src \ ServiceStack.Redis \ RedisNativeClient_Utils中的ServiceStack.Redis.RedisNativeClient.CreateResponseError(字符串错误) .cs:第146行    at ServiceStack.Redis.RedisNativeClient.ReadMultiDataResultCount()在C:\ Users \ barbers \ Desktop \ Downloads \ ServiceStack-ServiceStack.Redis-4add28a \ ServiceStack-ServiceStack.Redis-4add28a \ src \ ServiceStack.Redis \ RedisNativeClient_Utils.cs:line 578    at ServiceStack.Redis.Pipeline.QueuedRedisOperation.ProcessResult()在C:\ Users \ barbers \ Desktop \ Downloads \ ServiceStack-ServiceStack.Redis-4add28a \ ServiceStack-ServiceStack.Redis-4add28a \ src \ ServiceStack.Redis \ Pipeline \ QueuedRedisOperation。 cs:169行    在ServiceStack.Redis.RedisTransaction.Commit()中的C:\ Users \ barbers \ Desktop \ Downloads \ ServiceStack-ServiceStack.Redis-4add28a \ ServiceStack-ServiceStack.Redis-4add28a \ src \ ServiceStack.Redis \ Transaction \ RedisTransaction.cs: 100号线    位于C:\ Users \ barbers \ Desktop \ DocumentDBs \ DocumentDB.Redis \ RedisMessAround.cs:第63行中的DocumentDB.Redis.RedisMessAround.InsertInsideTransaction(Boolean shouldTransactionRollback)    在C:\ Users \ barbers \ Desktop \ DocumentDBs \ DocumentDB.Redis \ Program.cs中的DocumentDB.Redis.Program.Run():第45行    在C:\ Users \ barbers \ Desktop \ DocumentDBs \ DocumentDB.Redis \ Program.cs中的DocumentDB.Redis.Program.Main(String [] args):第18行    在System.AppDomain._nExecuteAssembly(RuntimeAssembly程序集,String [] args)    在System.AppDomain.ExecuteAssembly(String assemblyFile,Evidence assemblySecurity,String [] args)    在Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()    在System.Threading.ThreadHelper.ThreadStart_Context(对象状态)    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback callback,Object state,Boolean ignoreSyncCtx)    在System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback回调,对象状态)    在System.Threading.ThreadHelper.ThreadStart()

我认为Ok,Redis ServiceStack的人在单元测试中使用Transactions,所以我编辑了“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 个答案:

答案 0 :(得分:4)

您无法在同一交易中阅读和使用结果。

确保您了解MULTI / EXEC的工作原理: http://redis.io/topics/transactions

它有效地通过在一个复合命令中批量处理多个命令,该命令由Redis在1 go中发送和处理。

在您的示例中,您尝试使用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命令来指定事务将使用的所有变量。然后,如果在事务完成之前修改了这些变量中的任何一个,则将引发异常,并且不会执行任何排队的操作。