使用包StackExchange.Redis,可以在NuGet中下载到
可以支持多并发请求,保持数据一致性和不重复已经保证代码只再一次请求结束后再执行
public static async Task<bool> TryAcquireLockAsync()
{
bool isAcquired = false;
while (!isAcquired)
{
isAcquired = await _redisConn.GetDatabase().LockTakeAsync(_lockKey, "my_lock_instance", LockTimeout);
if (!isAcquired)
{
// 没有获取到锁,可以在这里等待一段时间再尝试
await Task.Delay(100); // 等待100毫秒
}
}
return isAcquired;
}
public static async Task ReleaseLockAsync()
{
await _redisConn.GetDatabase().LockReleaseAsync(_lockKey, "my_lock_instance");
}
/// <summary>
/// 获取锁
/// </summary>
/// <returns></returns>
public static bool TryAcquireLock()
{
bool isAcquired = false;
while (!isAcquired)
{
isAcquired = _redisConn.GetDatabase().LockTake(_lockKey, "my_lock_instance", LockTimeout);
if (!isAcquired)
{
// 没有获取到锁,可以在这里等待一段时间再尝试
Task.Delay(100); // 等待100毫秒
}
}
return isAcquired;
}
/// <summary>
/// 释放锁
/// </summary>
public static void ReleaseLock()
{
_redisConn.GetDatabase().LockReleaseAsync(_lockKey, "my_lock_instance");
}
本次代码使用在生成唯一Code的使用:
redis主要代码
//锁主要参数
private static readonly object Locker = new object();
private static ConnectionMultiplexer _redisConn;
private static readonly string LockKey = "redis_lock";
private static string _lockKey;
private static readonly TimeSpan AcquireTimeout = TimeSpan.FromSeconds(10);
private static readonly TimeSpan LockTimeout = TimeSpan.FromSeconds(30);
//配置参数
public static string RedisIp = AppConfigurtaionServices.Configuration["RedisSetting:Host"];
public static string RedisPort = AppConfigurtaionServices.Configuration["RedisSetting:Port"];
public static string RedisPwd = AppConfigurtaionServices.Configuration["RedisSetting:PassWord"];
private static ConfigurationOptions ConfigurationOptions = ConfigurationOptions.Parse($"{RedisIp}:{RedisPort},allowAdmin=true{(RedisPwd.IsNullOrEmpty() ? "" : $",{RedisPwd}")}");
/// <summary>
/// 单例获取
/// </summary>
public static ConnectionMultiplexer RedisConn
{
get
{
if (_redisConn == null)
{
InitConfiguration();
// 锁定某一代码块,让同一时间只有一个线程访问该代码块
lock (Locker)
{
if (_redisConn == null || !_redisConn.IsConnected)
{
_redisConn = ConnectionMultiplexer.Connect(ConfigurationOptions);
}
}
_lockKey = LockKey;
}
return _redisConn;
}
}
public static void InitConfiguration()
{
string password = RedisPwd.IsNullOrEmpty() ? "" : $",password ={RedisPwd}";
ConfigurationOptions = ConfigurationOptions.Parse($"{RedisIp}:{RedisPort},allowAdmin=true{password}");//
}
/// <summary>
/// 设置定时过期redis key
/// </summary>
/// <param name="key">键</param>
/// <param name="expireTime">过期时间 分钟</param>
/// <param name="dbs">redis db 默认db(1)</param>
public static void SetRedisExpireKey(string key, int expireTime, int dbs = 1)
{
//将订单和时间存住到redis中,走定时执行任务
TimeSpan expiry = TimeSpan.FromSeconds(expireTime * 60);
var db = _redisConn.GetDatabase(dbs);
db.StringSet($"{key}", ""
, expiry);
}
/// <summary>
/// 删除定时过期redis key
/// </summary>
/// <param name="key">键</param>
/// <param name="dbs">redis db默认db(1)</param>
public static void DeleteRedisExpireKey(string key, int dbs = 1)
{
var db = _redisConn.GetDatabase(dbs);
db.KeyDelete($"{key}");
}
#region Redis方法
public static bool Exists(string key)
{
var db = _redisConn.GetDatabase();
return db.KeyExists(key);
}
public static bool Exists(string key, int dbs = 0)
{
var db = _redisConn.GetDatabase(dbs);
return db.KeyExists(key);
}
public static string Get(string key)
{
var db = _redisConn.GetDatabase();
return db.StringGet(key);
}
public static bool Set(string key, string value)
{
var db = _redisConn.GetDatabase();
return db.StringSet(key, value);
}
public static bool SetStr(string key, string value, int dbs = 0)
{
var db = _redisConn.GetDatabase(dbs);
return db.StringSet(key, value);
}
public static string SetStrDelete(string key, int dbs = 0)
{
//将订单和时间存住到redis中,走定时执行任务
var db = _redisConn.GetDatabase(dbs);
return db.StringGetDelete(key);
}
public static bool Set(string key, string value, int expireTime)
{
//将订单和时间存住到redis中,走定时执行任务
TimeSpan expiry = TimeSpan.FromSeconds(expireTime * 60);
var db = _redisConn.GetDatabase();
return db.StringSet(key, value, expiry);
}
public static string SetStrDelete(string key)
{
//将订单和时间存住到redis中,走定时执行任务
var db = _redisConn.GetDatabase();
return db.StringGetDelete(key);
}
public static bool RemoveKey(string key)
{
var db = _redisConn.GetDatabase();
return db.KeyDelete(key);
}
public static bool RemoveKey(string key, int dbs = 0)
{
var db = _redisConn.GetDatabase(dbs);
return db.KeyDelete(key);
}
public static bool HashSet(string redisName, string key, string value)
{
var db = _redisConn.GetDatabase();
return db.HashSet(redisName, key, value);
}
public static bool HashSet(string redisName, string key, string value, int dbs = 0)
{
var db = _redisConn.GetDatabase(dbs);
return db.HashSet(redisName, key, value);
}
public static string HashGet(string redisName, string key)
{
var db = _redisConn.GetDatabase();
return db.HashGet(redisName, key);
}
public static string HashGet(string redisName, string key, int dbs = 0)
{
var db = _redisConn.GetDatabase(dbs);
return db.HashGet(redisName, key);
}
public static bool HashRemove(string redisName, string key)
{
var db = _redisConn.GetDatabase();
return db.HashDelete(redisName, key);
}
public static bool HashKeyExists(string redisName, string key)
{
var db = _redisConn.GetDatabase();
return db.HashExists(redisName, key);
}
public static IEnumerable<string> GetPageList(string hashKey,int pageIndex ,int pageSize)
{
var db = _redisConn.GetDatabase();
var start=(pageIndex - 1) * pageSize;
var end = pageIndex * pageSize-1;
var values= db.ListRange(hashKey, start, end);
return values.Select(x=>x.ToString());
}
public static bool HashKeyExists(string redisName, string key, int dbs = 0)
{
var db = _redisConn.GetDatabase(dbs);
return db.HashExists(redisName, key);
}
#endregion
public static async Task<bool> TryAcquireLockAsync()
{
bool isAcquired = false;
while (!isAcquired)
{
isAcquired = await _redisConn.GetDatabase().LockTakeAsync(_lockKey, "my_lock_instance", LockTimeout);
if (!isAcquired)
{
// 没有获取到锁,可以在这里等待一段时间再尝试
await Task.Delay(100); // 等待100毫秒
}
}
return isAcquired;
}
public static async Task ReleaseLockAsync()
{
await _redisConn.GetDatabase().LockReleaseAsync(_lockKey, "my_lock_instance");
}
/// <summary>
/// 获取锁
/// </summary>
/// <returns></returns>
public static bool TryAcquireLock()
{
bool isAcquired = false;
while (!isAcquired)
{
isAcquired = _redisConn.GetDatabase().LockTake(_lockKey, "my_lock_instance", LockTimeout);
if (!isAcquired)
{
// 没有获取到锁,可以在这里等待一段时间再尝试
Task.Delay(100); // 等待100毫秒
}
}
return isAcquired;
}
/// <summary>
/// 释放锁
/// </summary>
public static void ReleaseLock()
{
_redisConn.GetDatabase().LockReleaseAsync(_lockKey, "my_lock_instance");
}
}
调用方式:
/// <summary>
/// 获取新的条形码刷新数据,分布式控制
/// </summary>
/// <param name="orgCode"></param>
public static void SetOneTicketBarCode(string orgCode)
{
try
{
DateTime nowTime = DateTime.Now;
string StartTime = nowTime.AddSeconds(-5).ToString("yyyy-MM-dd HH:mm:ss");
string EndTime = nowTime.AddSeconds(5).ToString("yyyy-MM-dd HH:mm:ss");
var isLockAcquired = RedisHelper.TryAcquireLock();
if (isLockAcquired)
{
DataSet set = EntityBase.GetDB().GetDS($"select Code from MemberTicket where orgCode='{orgCode}' and TicketState in (0,1,3) and (BarCode is null or BarCode='') and crDate>='{StartTime}' and crDate<='{EndTime}';" +
$"select Code,BarCode from MemberTicket where orgCode='{orgCode}' and TicketState in (0,1,3) and crDate>='{StartTime}' and crDate<='{EndTime}';" +
$"select Code,BarCode from MemberTicket where orgCode='{orgCode}' and TicketState in (0,1,3) and (BarCode is null or BarCode='') and crDate>='{StartTime}' and crDate<='{EndTime}';");
if (set.Tables[0].Rows.Count > 0)
{
var dt = set.Tables[1];
var dthas = set.Tables[2];
List<string> list = new List<string>();
foreach (DataRow item in dthas.Rows)
{
if (!item.GetStringValue("BarCode").IsNullOrEmpty())
{
continue;
}
string BarCode = DateTime.Now.ToString("hmmssfff");
BarCode = (Convert.ToInt32(BarCode) + new Random().Next(0, 99999)).ToString();
while (list.Contains(BarCode))
{
BarCode = (Convert.ToInt32(BarCode) + new Random().Next(0, 99999)).ToString();
}
while (dt.AsEnumerable().Any(x => x.Field<string>("BarCode") == BarCode))
{
BarCode = (Convert.ToInt32(BarCode) + new Random().Next(0, 99999)).ToString();
}
list.Add(BarCode);
EntityBase entityBase = new EntityBase("MemberTicket");
entityBase.DoType = "Update";
entityBase.FieldValueList.Add("Code", new FieldValue() { Name = "Code", CurrentValue = item.GetStringValue("Code") });
entityBase.FieldValueList.Add("BarCode", new FieldValue() { Name = "BarCode", CurrentValue = BarCode });
entityBase.AddOrUpdate();
}
}
}
else
{
}
}
catch (Exception ex)
{
ErrorLogs.InsertErrorLog(LogType.Error, "生成条形码报错:" + ex.ToString());
}
finally
{
RedisHelper.ReleaseLock();
}
}