前几天,公司数据库出现了两条相同的数据,而且时间相同(毫秒也相同)。排查原因,发现是网络波动造成了重复提交。
由于网络波动而重复提交的例子也比较多:
公共类Cache
{
私人只读的ReaderWriterLockSlim _lock=new ReaderWriterLockSlim ();
私人只读的Dictionary_map=new Dictionary ();
公共int数{
{回报_map.Count;}
}
公共TValue执行(TKey键,Func工厂)
{//检查缓存
_lock.EnterReadLock ();
TValue val;
尝试{
如果(_map。TryGetValue(关键,val))
返回val;
最后}{
_lock.ExitReadLock ();
}//缓存
_lock.EnterWriteLock ();
尝试{//检查再一次
如果(_map。TryGetValue(关键,val))
返回val;//创建它
val=工厂();//存储
_map。添加(关键,val);//完成
返回val;
最后}{
_lock.ExitWriteLock ();
}
}
公共空间Clear ()
{//缓存
_lock.EnterWriteLock ();
尝试{
_map.Clear ();
最后}{
_lock.ExitWriteLock ();
}
}
}
Cache
但是,细细分析Cache类,可以发现有以下几个缺点
1,不会自动清空缓存,适合一些关键不多的数据,不适合做为网络接口。
2,由于_lock.EnterWriteLock,多线程会变成并单线程,不适合做为网络接口。
3,没有过期缓存判断。
于是我对Cache进行改造。
AntiDupCache代码如下:
///& lt; summary>///防重复缓存///& lt;/summary>///& lt; typeparam name=" TKey祝辞& lt;/typeparam>///& lt; typeparam name=" TValue祝辞& lt;/typeparam>
公共类AntiDupCache
{
私人只读的int _maxCount;//缓存最高数量
私人只读的长_expireTicks;//超时蜱虫
私人长_lastTicks;//最后蜱虫
私人只读的ReaderWriterLockSlim _lock=new ReaderWriterLockSlim ();
私人只读的ReaderWriterLockSlim _slimLock=new ReaderWriterLockSlim ();
私人只读的Dictionary比;_map=new Dictionary在();
私人只读的Dictionary_lockDict=new Dictionary ();
私人只读的Queue_queue=new Queue ();
类AntiDupLockSlim: ReaderWriterLockSlim{公共int UseCount;}///& lt; summary>///防重复缓存///& lt;/summary>///& lt;参数name=" maxCount祝辞缓存最高数量,0不缓存,1缓存所有& lt;/param>///& lt;参数name=" expireSecond祝辞超时秒数,0不缓存,1永久缓存& lt;/param>
公共AntiDupCache (int maxCount=100, int expireSecond=1)
{
如果(maxCount & lt;0){
_maxCount=1;
其他}{
_maxCount=maxCount;
}
如果(expireSecond & lt;0){
_expireTicks=1;
其他}{
.Ticks _expireTicks=expireSecond * TimeSpan.FromSeconds (1);
}
}///& lt; summary>///个数///& lt;/summary>
公共int数{
{回报_map.Count;}
}///& lt; summary>///执行///& lt;/summary>///& lt;参数name=肮丶弊4侵? lt;/param>///& lt;参数name="工厂"祝辞执行方法& lt;/param>///& lt; returns> & lt;/returns>
公共TValue执行(TKey键,Func工厂)
{//过期时间为0则不缓存
如果对象。=(null,键)| | _expireTicks==0 l | | _maxCount==0){返回工厂();}
TValue> Tuple