gpt4 book ai didi

c# - 需要中层帮助

转载 作者:太空狗 更新时间:2023-10-29 23:35:28 25 4
gpt4 key购买 nike

一句话,我最终需要知道的是如何在不需要应用程序层传递数据模型对象的情况下在中间层函数之间共享对象。

我正在为我工​​作的公司在我们当前的环境中构建一个中间层。目前,我们主要使用 .NET 进行编程,并围绕我们所有的各种数据库系统(包括 Oracle、OpenLDAP、MSSQL 等)构建了自定义数据模型。

我在尝试从应用程序层中提取我们的模型并将其移动到一系列中间层库中时遇到了问题。我遇到的主要问题是应用程序层能够在整个进程持续时间内卡在缓存对象上,并根据缓存数据进行更新,但中间层操作不能。

我试图尽可能地将模型对象保留在应用程序之外,以便在我们对底层数据库结构进行更改时,我们可以轻松地编辑和重新部署中间层,并且不需要重新构建多个应用程序。我将简要更新伪代码中的问题,因为这是我们开发人员最了解的内容:)

main
{
MidTierServices.UpdateCustomerName("testaccount", "John", "Smith");

// since the data takes up to 4 seconds to be replicated from
// write server to read server, the function below is going to
// grab old data that does not contain the first name and last
// name update.... John Smith will be overwritten w/ previous
// data

MidTierServices.UpdateCustomerPassword("testaccount", "jfjfjkeijfej");
}

MidTierServices
{
void UpdateCustomerName(string username, string first, string last)
{
Customer custObj = DataRepository.GetCustomer(username);

/*******************
validation checks and business logic go here...
*******************/

custObj.FirstName = first;
custObj.LastName = last;

DataRepository.Update(custObj);
}

void UpdateCustomerPassword(string username, string password)
{
// does not contain first and last updates
Customer custObj = DataRepository.GetCustomer(username);

/*******************
validation checks and business logic go here...
*******************/

custObj.Password = password;

// overwrites changes made by other functions since data is stale
DataRepository.Update(custObj);
}
}

附带说明一下,我考虑过的选项是构建一个自产的缓存层,这需要很多时间,而且是一个很难向管理层出售的概念。使用内置缓存支持的不同建模层,例如 nHibernate:这也很难卖给管理层,因为这个选项也需要很长时间才能拆开我们的整个自定义模型并用第三方解决方案替换它.此外,支持我们大量数据库的供应商并不多。例如,.NET 具有 LINQ to ActiveDirectory,但没有 LINQ to OpenLDAP。

不管怎样,对于这本小说很抱歉,但它更像是一个企业架构类型的问题,而不是一个简单的代码问题,例如“如何在 .NET 中获取当前日期和时间?”

编辑

抱歉,我忘了在原帖中添加一些非常重要的信息。我感觉很糟糕,因为 Cheeso 经历了很多麻烦来写一个非常深入的回复,如果没有更多的问题(我愚蠢地没有包括),这将解决我的问题。

我面临当前问题的主要原因是关注数据复制。第一个函数写入一个服务器,然后下一个函数从另一个尚未收到复制数据的服务器读取。所以本质上,我的代码比数据复制过程快。

我可以通过始终读取和写入同一个 LDAP 服务器来解决这个问题,但我的管理员可能会为此而谋杀我。专门设置一个只用于写入的服务器,然后在负载均衡器后面设置另外 4 个仅用于读取的服务器。我绝不是 LDAP 管理员,所以我不知道这是否是标准程序。

最佳答案

您正在描述一个非常常见的问题。

解决它的正常方法是通过使用 Optimistic Concurrency Control .

如果这听起来像 gobbledegook,那不是。这是一个非常简单的想法。该术语的并发部分指的是记录数据发生更新,并且这些更新同时发生。可能有很多作家。 (您的情况是一个退化的情况,其中一个作者是问题的根源,但它的基本思想是相同的)。乐观的部分我马上就会讲到。

问题

当有多个写入者时,两个更新的读写部分可能会交错。假设您有 A 和 B,他们都读取并更新数据库中的同一行。 A读取数据库,然后B读取数据库,然后B更新它,然后A更新它。如果你的方法很幼稚,那么“最后一次写入”将获胜,B 的写入可能会被破坏。

输入乐观并发。基本思想是假设更新会起作用,但请检查。有点像信任,但验证了几年前的军备控制方法。这样做的方法是在数据库表中包含一个字段,该字段也必须包含在域对象中,它提供了一种将 db 行或域对象的一个​​“版本”与另一个“版本”区分开的方法。最简单的方法是使用一个名为 lastUpdate 的时间戳字段,它保存上次更新的时间。还有其他更复杂的方法可以进行一致性检查,但时间戳字段非常适合用于说明目的。

然后,当作者或更新者想要更新数据库时,它只能更新键匹配的行(无论您的键是什么)以及 lastUpdate 匹配时。这是验证部分。

由于开发人员了解代码,我将提供一些伪 SQL。假设您有一个博客数据库,其中包含每个博客条目的索引、标题和一些文本。您可以像这样检索一组行(或对象)的数据:

SELECT ix, Created, LastUpdated, Headline, Dept FROM blogposts 
WHERE CONVERT(Char(10),Created,102) = @targdate

这种查询可能会检索数据库中给定日期、月份或其他时间的所有博客文章。

使用简单的乐观并发,您将使用 SQL 更新单行,如下所示:
UPDATE blogposts Set Headline = @NewHeadline, LastUpdated = @NewLastUpdated
WHERE ix=@ix AND LastUpdated = @PriorLastUpdated

只有在索引匹配时才会发生更新(我们假设这是主键),并且 LastUpdated 字段与读取数据时的字段相同。另请注意,您必须确保为该行的每次更新更新 LastUpdated 字段。

更严格的更新可能会坚持没有任何列被更新。在这种情况下,根本没有时间戳。像这样的东西:
UPDATE Table1 Set Col1 = @NewCol1Value,
Set Col2 = @NewCol2Value,
Set Col3 = @NewCol3Value
WHERE Col1 = @OldCol1Value AND
Col2 = @OldCol2Value AND
Col3 = @OldCol3Value

为什么叫“乐观”?

OCC 被用作持有数据库锁的替代方法,这是一种保持数据一致的严厉方法。数据库锁可能会阻止任何人读取或更新数据库行,同时它被持有。这显然具有巨大的性能影响。因此,OCC 放宽了这一点,并“乐观地”采取行动,假设需要更新时,表中的数据不会同时更新。但当然这不是盲目乐观 - 您必须在更新前检查。

在实践中使用乐观 Cancurrency

你说你使用.NET。我不知道您是否使用 DataSet 进行数据访问,强类型或其他方式。但是 .NET DataSets,或者特别是 DataAdapters,包括对 OCC 的内置支持。您可以为任何 DataAdapter 指定和手动编码 UpdateCommand,这是您可以插入一致性检查的地方。这也是 possible within the Visual Studio design experience .

alt text
(来源: asp.net)

如果您遇到违规,更新将返回一个结果,表明更新了零行。您可以在 DataAdapter.RowUpdated event 中查看此信息. (请注意,在 ADO.NET 模型中,每种数据库都有一个不同的 DataAdapter。该链接是用于 SqlDataAdapter 的,它适用于 SQL Server,但对于不同的数据源,您需要不同的 DA。)

在 RowUpdated 事件中,您可以检查受影响的行数,如果计数为零则采取一些措施。

摘要

在写入更新之前,请验证数据库的内容未被更改。这称为乐观并发控制。

其他链接:
  • MSDN on Optimistic Concurrency Control in ADO.NET
  • Tutorial on using SQL Timestamps for OCC
  • 关于c# - 需要中层帮助,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2113280/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com