要安全的批量pop数据,有两个办法:
1、用事务(不用事务的话可能导致重复读。ServiceStack的pipeline是没有自带事务的。)
2、执行lua脚本
我这里提供用事务的实现方法:
public static string ReadLine(RedisNativeClient cln) { MethodInfo mi = cln.GetType().GetMethod("ReadLine", BindingFlags.NonPublic | BindingFlags.Instance); string ret = (string)mi.Invoke(cln, new object[] { }); return ret; } public static List<string> BatchDequeue(RedisNativeClient cln, string listID, int max_count) { List<string> ret = new List<string>(); var uListId = Encoding.UTF8.GetBytes(listID); var pipeline = cln.CreatePipelineCommand(); pipeline.WriteCommand(Commands.Multi); pipeline.WriteCommand(Commands.LRange, uListId, Encoding.UTF8.GetBytes("0"), Encoding.UTF8.GetBytes((max_count - 1).ToString())); pipeline.WriteCommand(Commands.LTrim, uListId, Encoding.UTF8.GetBytes(max_count.ToString()), Encoding.UTF8.GetBytes("-1")); pipeline.WriteCommand(Commands.Exec); pipeline.Flush(); var a1 = ReadLine(cln); //忽略Multi的OK var a2 = ReadLine(cln); //忽略LRANGE的QUEUED var a3 = ReadLine(cln); //忽略LTRIM的QUEUED var a4 = ReadLine(cln); //忽略*2 var b = cln.ReceiveMessages(); foreach (var item in b) { string ss = Encoding.UTF8.GetString(item); ret.Add(ss); } ReadLine(cln); //忽略EXEC的OK return ret; }
时间: 2024-10-14 11:38:19