MDriven 为多个对象生成相同的 ECO_ID 似乎存在问题。在大多数情况下,它似乎与意外的进程关闭和/或服务器关闭一起发生,但它也确实发生在正常活动期间。
我们的系统由一个 ASP.NET 应用程序和一个 WinForms 应用程序组成。ASP.NET 应用程序在 IIS 中设置为使用单个工作进程。我们混合了 WebForms 和 MVC,包括 ApiControllers。我们使用的是相当旧的 ECO 包版本:7.0.0.10021。我们在 VS 2017 上,目标框架是 4.7.1。
我们将其配置为使用 64 位整数作为对象 id:s。数据库是火鸟。SQL 配置设置为使用 ReadCommitted 事务隔离。
据我所知,我们已经配置EcoSpaceStrategyHandler
了EcoSpaceStrategyHandler.SessionStateMode.Never
,这应该意味着 EcoSpaces 根本没有被重用,对吧?(为什么我什至会EcoSpaceStrategyHandler
在这种情况下使用,而不是使用new
关键字正常创建 EcoSpace?)
我们已经创建了用于所有控制器的类MasterController : Controller
。MasterApiController : ApiController
这些具有EcoSpace
简单地执行此操作的属性:
if (ecoSpace == null)
{
if (ecoSpaceStrategyHandler == null)
ecoSpaceStrategyHandler = new EcoSpaceStrategyHandler(
EcoSpaceStrategyHandler.SessionStateMode.Never,
typeof(DiamondsEcoSpace),
null,
false
);
ecoSpace = (DiamondsEcoSpace)ecoSpaceStrategyHandler.GetEcoSpace();
}
return ecoSpace;
即,如果没有创建策略处理程序,则创建一个指定生态空间不进行池化和会话状态持久化的处理程序。然后,如果没有获取生态空间,则从策略处理程序获取一个。返回生态空间。这是一种可接受的方法吗?为什么会比简单地这样做更好:
if (ecoSpace = null)
ecoSpace = new DiamondsEcoSpace();
return ecoSpace;
在 aspx 中,我们有一个母版页,其中包含EcoSpaceManager
. 它已被配置为使用一个池,但SessionStateMode
它是Never
. 它已EnableViewState
设置为true
。这可以接受吗?这是否意味着 EcoSpaces 将在往返之间汇集但停用?
我们可能会连续收到多个传入的 API 调用,因此一个 API 调用在下一个调用之前尚未完成。我假设这意味着多个实例MasterApiController
可以同时执行但在不同的线程中。当然也可能有MasterController
执行 MVC 请求的实例,并且 WinForms 应用程序可能正在运行一些批处理作业或其他。
但据我了解,id 预订是在任何UpdateDatabase
通话开始时进行的,方式如下:
update "ECO_ID" set "BOLD_ID" = "BOLD_ID" + :N;
select "BOLD_ID" from "ECO_ID";
如果返回值为 K,这将保留 N 个新的 id:s,范围从 K-N 到 K-1。在任何地方使用 ReadCommitted 事务应确保更新锁定 id 数据行,强制所有并发保存操作等待,然后获取在不受其他事务干扰的情况下更新结果,然后提交。此时,任何其他挂起的保存操作都可以继续进行自己的 id 保留。我看不出这会如何导致多个对象使用相同的 ID。
我应该注意到,它似乎有时会在一个单独的 UpdateDatabase 中产生 id 重复,即当保存一组新的相关对象时,其中一些最终具有相同的 id。我还没有真正证实这一点。
有什么想法可能会在这里发生吗?我应该寻找什么?