मुझे पता नहीं लगा सकता कि HasChanged
मेरे SqlCacheDependency
ऑब्जेक्ट का मूल्य मूल रूप से कमांड निष्पादन से वापस आ रहा है, लेकिन डेटाबेस से वापस आने के लगभग तुरंत बाद, मूल्य सही हो जाता है।मेरा एसक्ल कैश पर निर्भरता क्यों गलत है, लेकिन परिवर्तन के बाद लगभग तुरंत?
कभी-कभी यह कैश में भी डालने से पहले होता है, जिससे कैश इसे तुरंत त्याग देता है, कभी-कभी यह डालने के बाद होता है, और मैं एक गणनाकर्ता पकड़ सकता हूं जो कैश में कुंजी देखता है लेकिन इससे पहले कि मैं लूप भी उस आइटम को कैश में हटा दिया गया है।
sproc:
ALTER PROCEDURE [dbo].[ntz_dal_ER_X_Note_SelectAllWER_ID]
@ER_ID int
AS
BEGIN
SELECT
ER_X_Note_ID,
ER_ID,
Note_ID
FROM dbo.ER_X_Note e
WHERE
ER_ID = @ER_ID
END
डेटाबेस एमएस एसक्यूएल सर्वर 2008, दलाल सेवा सक्षम है, और कुछ उत्पादन कैश करता है और कैश की गई रहते हैं। उदाहरण के लिए, यह एक बस ठीक काम करता है:
ALTER PROC [dbo].[ntz_dal_GetCacheControllerByEntityName] (
@Name varchar(50)
) AS
BEGIN
SELECT
CacheController_ID,
EntityName,
CacheEnabled,
Expiration
From dbo.CacheController cc
WHERE EntityName = @Name
END
कोड जो सवाल में sproc कॉल विफल रहता है:
DataSet toReturn;
Hashtable paramHash = new Hashtable();
paramHash.Add("ER_ID", _eR_ID.IsNull ? null : _eR_ID.Value.ToString());
string cacheName = BuildCacheString("ntz_dal_ER_X_Note_SelectAllWER_ID", paramHash);
toReturn = (DataSet)GetFromCache(cacheName);
if (toReturn == null)
{
// Set up parameters (1 input and 0 output)
SqlParameter[] arParms = {
new SqlParameter("@ER_ID", _eR_ID),
};
SqlCacheDependency scd;
// Execute query.
toReturn = _dbTransaction != null
? _dbConnection.ExecuteDataset(_dbTransaction, "dbo.[ntz_dal_ER_X_Note_SelectAllWER_ID]", out scd, arParms)
: _dbConnection.ExecuteDataset("dbo.[ntz_dal_ER_X_Note_SelectAllWER_ID]", out scd, arParms);
AddToCache(cacheName, toReturn, scd);
}
return toReturn;
कोड है कि काम करता है
const string sprocName = "ntz_dal_GetCacheControllerByEntityName";
string cacheControlPrefix = "CacheController_" + CachePrefix;
CacheControl controller = (CacheControl)_cache[cacheControlPrefix];
if (controller == null)
{
try
{
SqlParameter[] arParms = {
new SqlParameter("@Name", CachePrefix),
};
SqlCacheDependency sqlCacheDependency;
// Execute query.
DataSet result = _dbTransaction != null
? _dbConnection.ExecuteDataset(_dbTransaction, sprocName, out sqlCacheDependency, arParms)
: _dbConnection.ExecuteDataset(sprocName, out sqlCacheDependency, arParms);
controller = result.Tables[0].Rows.Count == 0
? new CacheControl(false)
: new CacheControl(result.Tables[0].Rows[0]);
_cache.Insert(cacheControlPrefix, controller, sqlCacheDependency);
}
catch (Exception ex)
{
// if sproc retreival fails cache the result of false so we don't keep trying
// this is the only case where it can be added with no expiration date
controller = new CacheControl(false);
// direct cache insert, no dependency, no expiration, never try again for this entity
if (HttpContext.Current != null && UseCaching && _cache != null) _cache.Insert(cacheControlPrefix, controller);
}
}
return controller;
AddToCache
विधि ओवरलोड हो गया है और इसमें अधिक परीक्षण हैं; कामकाजी विधि में प्रत्यक्ष _cache.Insert
उन अन्य परीक्षणों को बाईपास करना है। कामकाजी कोड यह निर्धारित करने में मदद करता है कि क्या डीबी कैशिंग बिल्कुल होनी चाहिए।
आप देख सकते हैं कि जब "गैर काम कर रहे" डेटा शुरू में लिया गया है, सब ठीक है:
लेकिन उस बिंदु से परे कहीं यादृच्छिक, इस उदाहरण में, बस अगली विधि
में कदमऔर फिर भी डेटा बिल्कुल बदल नहीं रहा है; मैं डेटाबेस का इस उदाहरण को छूने वाला अकेला हूं।
मैं इसे आज़माउंगा, लेकिन मुझे लगता है कि यह असंभव है, क्योंकि परम हैश का उपयोग केवल उस कुंजी नाम को बनाने के लिए किया जाता है जिसके अंतर्गत कैश आइटम बनाया जाता है। –
@TheEvilGreebo: क्षमा करें, मुझे नहीं लगता कि मैंने काफी अच्छी तरह से संवाद किया है। मुझे लगता है कि समस्या कोड की यह पंक्ति है 'नया एसक्यूएल पैरामीटर ("@ ईआर_आईडी", _eR_ID) '। यह पूरे _eR_ID ऑब्जेक्ट को पैरामीटर पर पास करता है और मुझे यकीन नहीं है कि यह एसक्यूएल के मान के लिए कैसे अनुवाद करता है (मुझे संदेह है कि यह ऑब्जेक्ट पर ToString() को कॉल करता है)। इससे पहले कोड में आप _eR_ID.Value का उपयोग करते हैं, इसलिए मुझे लगता है कि आपको आवश्यक न्यूनतम परिवर्तन 'नया एसक्यूएल पैरामीटर ("@ ER_ID", _eR_ID.Value) 'है। –
ओह, मैं देखता हूं कि आपका क्या मतलब है। खैर _eR_ID एक SqlInt32 है - इसलिए कोई ऐसा सोचता है कि इसका उपयोग करके एक नया SqlParm प्रारंभ करना कोई समस्या नहीं पैदा करेगा, लेकिन इसकी कोशिश करने लायक है! –