delphi模拟redis单元
1 unit g_uSdRedis; 2 3 interface 4 5 uses 6 Windows, 7 Messages, 8 SysUtils, 9 Variants, 10 Classes, 11 Graphics, 12 Controls, 13 Forms, 14 Dialogs, 15 IniFiles, 16 StdCtrls, 17 DateUtils; 18 19 const 20 C_FORMAT_DATETIME_STLY_1 = 'yyyy-mm-dd hh:nn:ss.zzzz'; 21 C_FORMAT_DATETIME_STLY_2 = 'yyyy-mm-dd hh:nn:ss'; 22 C_FORMAT_DATETIME_STLY_3 = 'yyyymmddhhnnss'; 23 C_DEFAULT_EXPIRETIME = 1 * 60; 24 C_MAXLIMIT_COUNTS = 10000; 25 26 var 27 g_uMyRedis: THashedStringList; 28 g_uExpireTime: Integer = 1 * 60; 29 30 function getLockRedis(lockKey: string): string; 31 32 function addLockRedis(lockKey: string; expired: Integer): Boolean; 33 34 function delLockRedis(lockKey: string; nMaxLimitCounts: Integer): Boolean; 35 36 function delForceLockRedis(lockKey: string; nMaxLimitCounts: Integer): Boolean; 37 38 implementation 39 40 function initLoadHashMapParams(): Boolean; 41 begin 42 if not Assigned(g_uMyRedis) then 43 g_uMyRedis := THashedStringList.Create; 44 45 // 从配置文件中读取失效时间 46 g_uExpireTime := 10; 47 end; 48 49 function descHashMapParams(): Boolean; 50 begin 51 if Assigned(g_uMyRedis) then 52 FreeAndNil(g_uMyRedis); 53 end; 54 55 function addTimeSeconds(currTime: TDateTime; addSeconds: Integer): TDateTime; 56 begin 57 if addSeconds <= 0 then 58 begin 59 addSeconds := 1; 60 end; 61 Result := IncSecond(currTime, addSeconds); 62 end; 63 64 function getRedis(key: string): string; 65 var 66 iIndex: Integer; 67 sTmp: string; 68 begin 69 Result := ''; 70 try 71 iIndex := g_uMyRedis.IndexOfName(key); 72 if iIndex < 0 then 73 begin 74 Exit; 75 end; 76 sTmp := g_uMyRedis.Values[key]; 77 Result := sTmp; 78 except 79 on e:Exception do 80 begin 81 ShowMessage('【异常】通知:' + e.Message); 82 Exit; 83 end; 84 end; 85 end; 86 87 function setRedis(key: string; expired: Integer): Boolean; 88 var 89 iIndex: Integer; 90 nTime: Integer; 91 sTmp: string; 92 begin 93 Result := False; 94 try 95 iIndex := g_uMyRedis.IndexOfName(key); 96 if iIndex >= 0 then 97 begin 98 g_uMyRedis.Delete(iIndex); 99 end; 100 nTime := DateTimeToTimeStamp(addTimeSeconds(Now,expired)).Time; 101 sTmp := IntToStr(nTime); 102 g_uMyRedis.Add(key + '=' + sTmp); 103 Result := True; 104 except 105 on e:Exception do 106 begin 107 ShowMessage('【异常】通知:' + e.Message); 108 Exit; 109 end; 110 end; 111 end; 112 113 function setNXRedis(key: string; value: string): Boolean; 114 var 115 iIndex: Integer; 116 nTime: Integer; 117 sTmp: string; 118 begin 119 Result := False; 120 try 121 iIndex := g_uMyRedis.IndexOfName(key); 122 if iIndex >= 0 then 123 begin 124 Exit; 125 end; 126 g_uMyRedis.Add(key + '=' + value); 127 Result := True; 128 except 129 on e:Exception do 130 begin 131 ShowMessage('【异常】通知:' + e.Message); 132 Exit; 133 end; 134 end; 135 end; 136 137 function getSetRedis(key: string; value: string): String; 138 var 139 iIndex: Integer; 140 iDiffTime: Integer; 141 sTmp: string; 142 sNowDateTime: string; 143 begin 144 Result := ''; 145 try 146 sTmp := ''; 147 iIndex := g_uMyRedis.IndexOfName(key); 148 if iIndex >= 0 then 149 begin 150 sTmp := g_uMyRedis.Values[key]; 151 g_uMyRedis.Delete(iIndex); 152 end; 153 g_uMyRedis.Add(key + '=' + value); 154 Result := sTmp; 155 except 156 on e:Exception do 157 begin 158 ShowMessage('【异常】通知:' + e.Message); 159 Exit; 160 end; 161 end; 162 end; 163 164 function acquireLockRedis(lockKey: string; expired: Integer): Boolean; 165 var 166 iIndex: Integer; 167 nOldTime: Integer; 168 nNowTime: Integer; 169 nTime: Integer; 170 bRetBool: Boolean; 171 sOldDateTime: string; 172 sNowDateTime: string; 173 sTmp: string; 174 begin 175 Result := False; 176 try 177 if expired < 0 then 178 begin 179 expired := C_DEFAULT_EXPIRETIME; 180 end; 181 nTime := DateTimeToTimeStamp(addTimeSeconds(Now,expired)).Time; 182 sNowDateTime := IntToStr(nTime); 183 bRetBool := setNXRedis(lockKey, sNowDateTime); 184 if bRetBool then 185 begin 186 Result := True; 187 Exit; 188 end; 189 sOldDateTime := getRedis(lockKey); 190 nOldTime := StrToInt(sOldDateTime); 191 nNowTime := DateTimeToTimeStamp(Now).Time; 192 if nOldTime < nNowTime then 193 begin 194 sTmp := getSetRedis(lockKey, sNowDateTime); 195 if StrToInt(sTmp) = nOldTime then 196 begin 197 Result := True; 198 Exit; 199 end; 200 end; 201 except 202 on e:Exception do 203 begin 204 ShowMessage('【异常】通知:' + e.Message); 205 Exit; 206 end; 207 end; 208 end; 209 210 function releaseLockRedis(lockKey: string): Boolean; 211 var 212 iIndex: Integer; 213 begin 214 Result := False; 215 try 216 iIndex := g_uMyRedis.IndexOfName(lockKey); 217 if iIndex < 0 then 218 begin 219 Result := True; 220 Exit; 221 end; 222 g_uMyRedis.Delete(iIndex); 223 Result := True; 224 except 225 on e:Exception do 226 begin 227 ShowMessage('【异常】通知:' + e.Message); 228 Exit; 229 end; 230 end; 231 end; 232 233 function getLockRedis(lockKey: string): string; 234 var 235 iIndex1,iIndex2: Integer; 236 sTmp1: string; 237 sTmp2: string; 238 sKey: string; 239 sValue: string; 240 a: TTimeStamp; 241 begin 242 Result := ''; 243 try 244 iIndex1 := g_uMyRedis.IndexOfName(lockKey); 245 if iIndex1 < 0 then 246 begin 247 Exit; 248 end; 249 250 sTmp1 := g_uMyRedis.Strings[iIndex1]; 251 sTmp2 := ''; 252 iIndex2 := Pos('=', sTmp1); 253 if iIndex2 > 0 then 254 begin 255 sKey := Copy(sTmp1,1,iIndex2-1); 256 sValue := Copy(sTmp1,iIndex2+1,Length(sTmp1)-iIndex2); 257 a.Time := StrToInt(sValue); 258 a.Date := DateTimeToTimeStamp(Now).Date; 259 sTmp2 := FormatDateTime('yyyy-mm-dd hh:nn:ss.zzzz', TimeStampToDateTime(a)); 260 end; 261 Result := sTmp1 + '(' + sTmp2 + ')'; 262 except 263 on e:Exception do 264 begin 265 ShowMessage('【异常】通知:' + e.Message); 266 Exit; 267 end; 268 end; 269 end; 270 271 function addLockRedis(lockKey: string; expired: Integer): Boolean; 272 var 273 iIndex: Integer; 274 nOldTime: Integer; 275 nNowTime: Integer; 276 bRetBool: Boolean; 277 sOldDateTime: string; 278 sNowDateTime: string; 279 sTmp: string; 280 begin 281 Result := False; 282 try 283 if expired < 0 then 284 begin 285 expired := C_DEFAULT_EXPIRETIME; 286 end; 287 Result := acquireLockRedis(lockKey, expired); 288 except 289 on e:Exception do 290 begin 291 ShowMessage('【异常】通知:' + e.Message); 292 Exit; 293 end; 294 end; 295 end; 296 297 function delLockRedis(lockKey: string; nMaxLimitCounts: Integer): Boolean; 298 var 299 i: Integer; 300 nTime: Integer; 301 iSize: Integer; 302 nIndex: Integer; 303 sTmp: string; 304 sKey: string; 305 sValue: string; 306 begin 307 Result := False; 308 try 309 if lockKey <> '' then 310 begin 311 if getRedis(lockKey) <> '' then 312 begin 313 sTmp := g_uMyRedis.Values[lockKey]; 314 nTime := StrToInt(sTmp); 315 if DateTimeToTimeStamp(Now).Time > nTime then 316 begin 317 releaseLockRedis(lockKey); 318 end; 319 end; 320 end; 321 iSize := g_uMyRedis.Count; 322 if iSize > nMaxLimitCounts then 323 begin 324 if (nMaxLimitCounts <= 0) 325 and (nMaxLimitCounts >= 100000) then 326 begin 327 nMaxLimitCounts := C_MAXLIMIT_COUNTS; 328 end; 329 for i := iSize-1 downto 0 do 330 begin 331 sTmp := g_uMyRedis.Strings[i]; 332 nIndex := Pos('=',sTmp); 333 if nIndex > 0 then 334 begin 335 sKey := Copy(sTmp,1,nIndex-1); 336 sValue := Copy(sTmp,nIndex+1,Length(sTmp)-nIndex); 337 nTime := StrToInt(sValue); 338 if DateTimeToTimeStamp(Now).Time > nTime then 339 begin 340 releaseLockRedis(sKey); 341 end; 342 end; 343 end; 344 end; 345 Result := True; 346 except 347 on e:Exception do 348 begin 349 ShowMessage('【异常】通知:' + e.Message); 350 Exit; 351 end; 352 end; 353 end; 354 355 function delForceLockRedis(lockKey: string; nMaxLimitCounts: Integer): Boolean; 356 var 357 i: Integer; 358 nTime: Integer; 359 iSize: Integer; 360 nIndex: Integer; 361 sTmp: string; 362 sKey: string; 363 sValue: string; 364 begin 365 Result := False; 366 try 367 if lockKey <> '' then 368 begin 369 if getRedis(lockKey) <> '' then 370 begin 371 releaseLockRedis(lockKey); 372 end; 373 end; 374 iSize := g_uMyRedis.Count; 375 if iSize > nMaxLimitCounts then 376 begin 377 if (nMaxLimitCounts <= 0) 378 and (nMaxLimitCounts >= 100000) then 379 begin 380 nMaxLimitCounts := C_MAXLIMIT_COUNTS; 381 end; 382 for i := iSize-1 downto 0 do 383 begin 384 sTmp := g_uMyRedis.Strings[i]; 385 nIndex := Pos('=',sTmp); 386 if nIndex > 0 then 387 begin 388 sKey := Copy(sTmp,1,nIndex-1); 389 sValue := Copy(sTmp,nIndex+1,Length(sTmp)-nIndex); 390 nTime := StrToInt(sValue); 391 if DateTimeToTimeStamp(Now).Time > nTime then 392 begin 393 releaseLockRedis(sKey); 394 end; 395 end; 396 end; 397 end; 398 Result := True; 399 except 400 on e:Exception do 401 begin 402 ShowMessage('【异常】通知:' + e.Message); 403 Exit; 404 end; 405 end; 406 end; 407 408 409 initialization 410 initLoadHashMapParams; 411 412 413 finalization 414 descHashMapParams(); 415 416 end.
1 unit Unit1; 2 3 interface 4 5 uses 6 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 7 Dialogs, IniFiles, StdCtrls, JclHashMaps, g_uSdRedis; 8 9 type 10 TForm1 = class(TForm) 11 btn1: TButton; 12 edt1: TEdit; 13 btn2: TButton; 14 btn3: TButton; 15 procedure btn1Click(Sender: TObject); 16 procedure btn2Click(Sender: TObject); 17 procedure btn3Click(Sender: TObject); 18 private 19 { Private declarations } 20 public 21 { Public declarations } 22 end; 23 24 var 25 Form1: TForm1; 26 27 implementation 28 29 {$R *.dfm} 30 31 procedure TForm1.btn1Click(Sender: TObject); 32 var 33 i, aSize: Integer; 34 bRet: Boolean; 35 begin 36 edt1.Text := ''; 37 bRet := addLockRedis('AB123', 10); 38 try 39 edt1.Text := '开始加锁->'; 40 finally 41 delLockRedis('AB123', 1); 42 end; 43 edt1.Text := edt1.Text + '结束加锁->' + getLockRedis('AB123') + '#' + BoolToStr(bRet,True); 44 end; 45 46 procedure TForm1.btn2Click(Sender: TObject); 47 var 48 i, aSize: Integer; 49 begin 50 edt1.Text := ''; 51 addLockRedis('AB456', 10); 52 try 53 edt1.Text := '开始加锁->'; 54 finally 55 delLockRedis('AB456', 1); 56 end; 57 edt1.Text := edt1.Text + '结束加锁->' + getLockRedis('AB456'); 58 end; 59 60 procedure TForm1.btn3Click(Sender: TObject); 61 var 62 i, aSize: Integer; 63 begin 64 edt1.Text := ''; 65 addLockRedis('AB789', 10); 66 try 67 edt1.Text := '开始加锁->'; 68 finally 69 delLockRedis('AB789', 1); 70 end; 71 edt1.Text := edt1.Text + '结束加锁->' + getLockRedis('AB789'); 72 end; 73 74 end.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
2018-12-22 Delphi 时间转换异常处理(各Win系统时间显示格式不同)