在代码中查询Sitecore数据库有时不会返回任何内容

时间:2014-05-01 16:25:22

标签: sitecore

我们正在使用Sitecore 6.5 r111230。

我们有一个定制严格的Sitecore解决方案(基本上由第三方设计机构提供给我们;它基本上没有文档记录,我们不再与它们有任何业务安排),这些解决方案通过C#代码查找大量使用Sitecore项目。最终,多个抽象层调用Sitecore.Data.Database.GetItem(path),其中path是正常的站点核心查询。

间歇性地,此调用对于一个常量的路径返回null,引用我知道存在且未更改的项。我已经通过单步执行Visual Studio中的代码看到了这种情况。

我们认为这与索引有关,因为当索引(包含看不见的项目)被重建时,sitecore日志会定期填满FileNotFoundException或UnauthorisedAccessException。但是,在查看了文档后,您必须明确查询Index实例以从索引中检索项目,并且在内容编入索引时没有“魔力”将调用重定向到Database 。因此,我现在已将此作为问题的原因。

可能导致这种奇怪行为的原因是什么?

编辑#1:

在我发布问题后不久,我就想到了一个想法。该解决方案包括一个自定义索引重建处理程序,它处理发布事件的结束并在其中一个自定义索引上启动索引重建作业。如果此作业崩溃,因为(例如)运行它的帐户对存储索引的文件夹没有适当的权限,是否可以中止触发它的发布?观察支持这一想法,即'authoring'应用程序(从master运行)运行的查询似乎工作正常,而'delivery'应用程序(在web上)失败。这对我来说是一个失败的发布 - 虽然它们都是在发布之前已经存在的所有项目。如果可能的话,我怎么验证这是原因?

编辑#2:

更奇怪的是,在同一个站点上,据我所知,从同一台机器上提供服务(尽管有两个负载均衡),浏览同一页面的不同用户会得到不同的结果,其中返回的项目是不变的,不依赖于用户。我感到困惑,现在感到神秘。

编辑#3:

我可能更接近于弄清楚这里发生了什么。间歇性丢失的项目位于具有类似文件夹的模板的项目层次结构中,并通过路径访问。在过去的某个时间,原始项目被重命名为“备份”和创建了原始名称的新项目,并且在进行一些增量更改之前将项目复制到其中以保留层次结构。

我认为这个问题与预取缓存有关,预取缓存有一个由项(现在重命名的项)的id标识的条目。我假设当应用程序启动时,预取高速缓存加载旧项目的子项,解释“丢失”项目(现在存在但在我们备份时不在旧文件夹中)或'错误的'(那里有那些,但已经改变了)。当从CM发布任何内容或保存项目时,使用正确的数据重建更高级别的缓存,问题就会消失,因此看起来“间歇性”。

对于那些熟悉Sitecore的人:如果配置错误,预取缓存可以执行此操作吗?

3 个答案:

答案 0 :(得分:2)

以下是您可以查看的一些内容:

  1. 有些代码正在切换上下文数据库。如果数据在Web中,并且数据在Master中,是否有任何代码将上下文数据库切换到“Core”?然后查询将找不到该项,因为它正在查找错误的数据库。
  2. 有些代码正在切换语言。如果数据存在,但没有任何内容返回,则可能是该语言没有版本。是否有任何代码以编程方式切换上下文语言?
  3. 数据缓存已损坏我还没有看到索引重建或发布之前在GetItem调用上没有返回的原因项目,但我确实看到缓存清除问题导致Sitecore相信item不存在,因为它清除了数据但后来没有再次将其重新加载到缓存中。如果您执行完全缓存刷新(使用admin \ Cache.aspx),它会立即解决问题吗?

答案 1 :(得分:1)

要排除的一些事情:

  • 如果API调用完全按照您的描述进行;问题不在于Sitecore Query相关。 Database.GetItem()不使用Sitecore Query
  • 它也不能进行版本控制或语言切换。在这两种情况下,即使没有上下文语言版本,您也会获得Item的非null结果
  • 它也不能与索引相关,因为Database.GetItem不使用索引来检索结果
  • 它与权限无关,如果 - 正如您声明的那样 - 代码位于SecurityDisabler()

那么我们还剩下什么?说实话,我认为你可能在某个地方有一个错误的假设 - GetItem()调用返回null,因此可能有其他一些副作用。您可能会看到副作用,并得出结论,它必须是返回null的GetItem调用。我相信情况就是这样,因为你说你在两个不同的浏览器上得到不同的结果,浏览同一个盒子(服务器)。在我看来,这个问题的候选人越有可能是:

  • 您的scalabilitySettings.config未启用。这可能会在多服务器设置中给您带来问题。但是,它不会考虑您描述的结果,其中两个不同的浏览器在同一服务器上查看同一页面会产生不同的结果。但是,它可以解释为什么.GetItem()将返回结果一个服务器而不是另一个服务器
  • 缓存。更具体地说,在所讨论的控件/组件上配置的每用户缓存。这不会使你的.GetItem()返回null,但它可能会让你误入歧途并让你相信它。我需要了解更多关于您的解决方案以得出任何结论。每用户缓存是Sitecore解决方案中极少数可以解释同一个框上两个单独浏览会话的不同行为的事情之一
  • 上下文数据库不符合您的期望。通常只有在您执行位于站点根目录之外的定制.aspx页面时才会发生这种情况。你所写的任何内容似乎都没有表明这种情况。

希望这会有所帮助。有助于更多地了解导致您怀疑的症状.GetItem,或更多关于解决方案的一般信息。

答案 2 :(得分:0)

我首先要验证服务器上的数据库配置引用。 - 连接字符串指向相同的数据库 - 数据库定义与正确的连接字符串相关联 - 网站定义使用相同的数据库

添加Jay和Maras的评论检查您是否有任何带有短划线'-'或以0开头的项目。如果是这样,您将需要添加逻辑来包装带有'#'符号的逻辑。像这样:/sitecore/content/home/#folder-name#/year/#0001#