c# - 从Azure Redis缓存插入或删除值时,是否需要在代码级别进行同步?

标签 c# caching redis locking azure-redis-cache

我正在使用以下单例类为我的一项个人开发工作从Azure Redis缓存获取/设置/删除值。

using StackExchange.Redis;
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace PoC
{
    public sealed class CacheManager
    {
        public static object mutex = new object();

        public static string EndPoint { get; set; }
        public static string Password { get; set; }
        public static bool UseSsl { get; set; }
        public static int ConnectRetry { get; set; }
        public static int KeepAlive { get; set; }
        public static int ConnectTimeout { get; set; }

        private static ConfigurationOptions ConfigurationOptions;

        private static readonly CacheManager instance = new CacheManager();

        // Explicit static constructor to tell C# compiler
        // not to mark type as beforefieldinit
        static CacheManager() { }

        private CacheManager()
        {
            ConfigurationOptions = new ConfigurationOptions
            {
                Password = Password,
                Ssl = UseSsl,
                AbortOnConnectFail = false,
                ConnectRetry = ConnectRetry,
                KeepAlive = KeepAlive,
                ConnectTimeout = ConnectTimeout
            };
        }

        public static CacheManager Instance { get { return instance; } }

        public static string ConnectionString { get; set; }

        Lazy<ConnectionMultiplexer> lazyConnection = new Lazy<ConnectionMultiplexer>(() =>
        {
            return ConnectionMultiplexer.Connect(ConfigurationOptions);
        });

        IDatabase Database => lazyConnection.Value.GetDatabase();


        public void Set<T>(string key, T value)
        {
            lock (mutex)
            {
                Database.StringSet(key, ToByteArray(value));
            }
        }

        public T Get<T>(string key)
        {
            T result = FromByteArray<T>(Database.StringGet(key));
            return result;
        }

        public bool Remove(string key)
        {
            lock (mutex)
            {
                var removed = Database.KeyDelete(key);
                return removed;
            }
        }

        public byte[] ToByteArray<T>(T obj)
        {
            if (obj == null)
                return null;
            BinaryFormatter bf = new BinaryFormatter();
            using (MemoryStream ms = new MemoryStream())
            {
                bf.Serialize(ms, obj);
                return ms.ToArray();
            }
        }

        public T FromByteArray<T>(byte[] data)
        {
            if (data == null)
                return default(T);
            BinaryFormatter bf = new BinaryFormatter();
            using (MemoryStream ms = new MemoryStream(data))
            {
                object obj = bf.Deserialize(ms);
                return (T)obj;
            }
        }
    }
}



在这里,我在将值插入数据库或从数据库中删除值时使用了锁。但是从下面的帖子中,我知道Redis是一个单线程数据库,并且所有操作都是原子的-

Is there any lock mechanism in Azure Redis Cache while updating an item?

因此,我相信我使用的锁是不必要的,并且可能导致某些性能问题。如果我错了,请纠正我。我在Application_Start事件中设置了变量(端点,密码等)。希望能有所帮助。

最佳答案

您可以了解如何在Redis中使用WATCHhttps://stackexchange.github.io/StackExchange.Redis/Transactions.html

WATCH key  
isFieldExists = HEXISTS key, field  
if isFieldExists is 1  
MULTI  
HSET key, field, value  
EXEC  
else  
UNWATCH  
return isFieldExists

例:
var newId = CreateNewId();
var tran = db.CreateTransaction();
tran.AddCondition(Condition.HashNotExists(custKey, "UniqueID"));
tran.HashSetAsync(custKey, "UniqueID", newId);
bool committed = tran.Execute();

关于c# - 从Azure Redis缓存插入或删除值时,是否需要在代码级别进行同步?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62337919/

相关文章:

C# 创建/修改/读取 .xlsx 文件

c# - 分析 ASP.NET Web 服务的使用

caching - plone.app.caching 仅用于首页

redis - Redis中的"Grouping"数据

mysql - 带 mysql 和 redis 的 Tornado websockets

c# - 捕获来自 WebService 的传入参数

c# - 我的 mvc 应用程序中出现防伪错误

php - 定期用查询填充 View 数据

php - Redis中存储树结构

javascript - redis php 和 javascript 连接