zoukankan      html  css  js  c++  java
  • c# redis 利用锁(StackExchange.Redis LockTake)来保证数据在高并发情况下的正确性

    之前有写过一篇介绍c#操作redis的文章 http://www.cnblogs.com/axel10/p/8459434.html ,这篇文章中的案例使用了StringIncrement来实现了高并发情况下key值的稳定增加,但如果要用锁的方式而不是StringIncrement方法,那该怎么做呢?

    LockTake涉及到三个参数:key,token和TimeSpan,分别表示redis数据库中该锁的名称、锁的持有者标识和有效时间。下面将用一个多线程增加key值的案例来演示LockTake/LockRelease的用法。

    using StackExchange.Redis;
    using StackExchange.Redis.Extensions.Core;
    using StackExchange.Redis.Extensions.Core.Configuration;
    using StackExchange.Redis.Extensions.Newtonsoft;
    using System;
    using System.Threading;
    
    namespace RedisTest
    {
        class Program
        {
            static RedisValue Token = Environment.MachineName;
            static RedisKey Key = "lock";
    
            static void Ins()
            {
                Thread thread = new Thread(() =>
                {
                    for (int i = 0; i < 100; i++)
                    {
    
                        if (client.Database.LockTake(Key, Token, TimeSpan.MaxValue))   //key表示的是redis数据库中该锁的名称,不可重复。 Token用来标识谁拥有该锁并用来释放锁。TimeSpan表示该锁的有效时间。
                        {
                            try
                            {
                                int key = client.Get<int>("key");
    
                                client.Add("key", key + 10);
                            }
                            catch (Exception e)
                            {
                                Console.WriteLine(e);
                                throw;
                            }
                            finally
                            {
                                client.Database.LockRelease(Key, Token);
                            }
                        }
                        else
                        {
                            Console.WriteLine("locking");
                            while (!TryAgain(10))
                            {
                                Thread.Sleep(1);
                            }
                        }
                    }
                });
                thread.Start();
            }
    
            private static StackExchangeRedisCacheClient client;
    
    
            static void Main(string[] args)
            {
                var redisConfiguration = new RedisConfiguration() //配置
                {
                    Hosts = new RedisHost[]
                    {
                        new RedisHost() {Host = "127.0.0.1", Port = 6379}
                    }
                };
    
    
                client = new StackExchangeRedisCacheClient(new NewtonsoftSerializer(), redisConfiguration);
                client.Add("key", 0);
    
                for (int j = 0; j < 10; j++)
                {
                    Ins();
                }
    
                Thread.Sleep(2000);
    
                int i = client.Get<int>("key");
                Console.WriteLine(i);
                Console.ReadKey();
            }
    
            static bool TryAgain(int value)
            {
                if (client.Database.LockTake(Key, Token, TimeSpan.MaxValue))
                {
                    try
                    {
                        int key = client.Get<int>("key");
    
                        client.Add("key", key + value);
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e);
                        throw;
                    }
                    finally
                    {
                        client.Database.LockRelease(Key, Token);
                    }
    
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }
    }
  • 相关阅读:
    c语言基础学习10_文件操作02
    c语言_文件操作_FILE结构体小解释
    初识 Swift编程语言(中文版)
    Jquery滑动门实现
    【一步一步走(1)】远程桌面软件VNC的安装与配置
    并查集 路径压缩(具体解释)
    linux中操作java进程
    HDOJ 3944 DP?
    选择排序与冒泡排序
    UVa145 Gondwanaland Telecom
  • 原文地址:https://www.cnblogs.com/axel10/p/9001800.html
Copyright © 2011-2022 走看看