Redis事务Transaction管道PipeLine分布式锁

文章中我们将对ServiceStack和Stackexchange两种进行分别整理说明

一、ServiceStack使用方式

   1、事务Transaction        

public void TransactionTest()
{
    using (var redisClient = RedisBase.IRedisClient)
    {
        using (var tran = redisClient.CreateTransaction())
        {
            try
            {
                tran.QueueCommand(p =>
                {
                    //操作redis数据命令
                    redisClient.SetEntryInHash("hashId", "hashKey", "values");
                    long i = redisClient.IncrementValueBy("name", 1);
                });
                //提交事务
                tran.Commit();
            }
            catch
            {
                //回滚事务
                tran.Rollback();
            }
        }
    }
}

   2、管道PipeLine

/// <summary>
/// 管道批处理
/// </summary>
/// <param name="Key"></param>
public void PipeLineTest(string Key)
{
    using (var redisClient = RedisBase.IRedisClient)
    {
        using (var pipeline = redisClient.CreatePipeline())
        {
            try
            {
                pipeline.QueueCommand(r => r.SetValue(Key, "1"));
                pipeline.QueueCommand(r => r.IncrementValue(Key));
                pipeline.QueueCommand(r => r.IncrementValue(Key));
                pipeline.Flush();
            }
            catch
            {
            }
        }
    }
}

   3、分布式锁

/// <summary>
/// Setnx方式进行锁操作
/// </summary>
/// <param name="key"></param>
/// <returns>是否正确执行锁后操作</returns>
public bool DistributedLock_Setnx(string key)
{
    var lockkey = "lock_" + key;
    using (var redisClient = RedisBase.IRedisClient)
    {
        try
        {
            var lockresult = redisClient.SetValueIfNotExists(lockkey, "1", TimeSpan.FromSeconds(5));//
            if (lockresult)
            {
                //执行锁后的逻辑操作
                return true;
            }
            return false;
        }
        catch (Exception ex)
        {
        }
        finally
        {
            redisClient.Remove(lockkey);
        }
    }
    return false;
}


static string Token = Environment.MachineName;
/// <summary>
/// AcquireLock方式进行锁操作
/// </summary>
/// <param name="key"></param>
/// <returns>是否正确执行锁后操作</returns>
public bool DistributedLock(string key)
{
    using (var redisClient = RedisBase.IRedisClient)
    {
        redisClient.Add(key, 1);
        // 支持IRedisTypedClient和IRedisClient
        using (redisClient.AcquireLock(key))
        {
            Console.Write("申请并发锁<br/>");
            var counter = redisClient.Get<int>(key);
            Thread.Sleep(100);
            redisClient.Set("mykey", counter + 1);
            Console.Write(redisClient.Get<int>(key));
        }
    }
    return false;
}
static object myLock = new object();
/// <summary>
/// 代码级锁实现锁
/// </summary>
/// <param name="key">数据key</param>
static void StringLock(string key)
{
    using (var redisClient = RedisBase.IRedisClient)
    {
        lock (myLock)
        {
            redisClient.SetValue(key, "value值", TimeSpan.FromSeconds(5));
        }
    }
}

二、StackExchange.Redis方式

   1、事务Transaction        

/// <summary>
/// 执行事务
/// </summary>
/// <param name="keyValuePairs">键值对</param>
/// <param name="watchKey">watch的key,发生变化,事务不提交</param>
/// <returns></returns>
public bool ExecTransaction(Dictionary<string, object> keyValuePairs, string watchKey)
{
    IDatabase db = redisClient;
    var tran = db.CreateTransaction();
    if (!string.IsNullOrEmpty(watchKey))
        tran.AddCondition(Condition.StringEqual(watchKey, watchKey));
    Debug.WriteLine("tran begin");
    foreach (var item in keyValuePairs)
    {
        tran.StringSetAsync(item.Key, (int)item.Value);
    }
    bool result = tran.Execute();
    return result;
}

   2、管道PipeLine

/// <summary>
/// 执行批量操作
/// </summary>
/// <param name="keyValuePairs"></param>
public void ExecPipeLine(Dictionary<string, string> keyValuePairs)
{
    var batch = redisClient.CreateBatch();
    foreach (var item in keyValuePairs)
    {
        batch.StringSetAsync(item.Key, item.Value);
    }
    batch.Execute();
}

   3、分布式锁

/// <summary>
/// 使用Setnx进行锁操作
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public bool ExecLock_Setnx(string key)
{
    var setnx = redisClient.StringSet("LockKey", Token, TimeSpan.FromSeconds(5), when: When.NotExists);
    if (setnx)
    {
        //执行锁后操作
        redisClient.StringSet(key, "值");
        return true;
    }
    return false;
}
/// <summary>
/// StackExchange.redis锁
/// </summary>
/// <param name="key">数据Key</param>
/// <returns></returns>
public bool ExecLock(string key)
{
    var flag = false;
    //设置timespan避免死锁
    if (redisClient.LockTake("LockKey", Token, TimeSpan.FromSeconds(5)))
    {
        try
        {
            var tmp = redisClient.StringGet(key);
            var data = 0;
            int.TryParse(tmp, out data);
            redisClient.StringSet(key, data + 1);
            //redisClient.StringSet(key, data + 1,when:When.NotExists);//setnx
            flag = true;
        }
        catch (Exception)
        {
            //var a = ex.Message + "\r\n" + ex.StackTrace;
            var b = string.Empty;
        }
        finally
        {
            redisClient.LockRelease("LockKey", Token);
        }
    }
    return flag;
}
static object myLock = new object();
/// <summary>
/// 代码级锁实现锁
/// </summary>
/// <param name="key">数据key</param>
static void StringLock(string key)
{
    lock (myLock)
    {
        redisClient.StringSet(key, "value值", TimeSpan.FromSeconds(5));
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值