【问题标题】:Regulate access to resources like DB and filesystem规范对数据库和文件系统等资源的访问
【发布时间】:2014-11-11 21:23:08
【问题描述】:

我面临以下情况:

我正在开发的系统有几个不同的部分(服务和 ASP.net),各自负责。这些部分由 2 个资源组合在一起:MSSQL-DB 和 windows 文件系统上的文件。

目前所有这些部分都单独访问这些资源。我认为这会导致不可预测性和不一致。

我正在考虑引入一项服务来规范对这些资源的访问。我不确定这是否是公认的设计原则。

一般问题是:

我应该考虑什么样的解决方案,在设计时应该注意什么?

具体问题:

  • 这只是一个数据访问层吗?

  • 引入这样的 SPOF 是不是很糟糕?

  • 您能推荐任何针对这种解决方案的阅读材料吗? (特别是如果有 C# 的特定材料)

因为 allen-smithee 提出的一个好问题而编辑:

数据库当前由嵌入式查询访问。它们被分离到一个类中,但每个服务都不同,因此它不是共享库。

【问题讨论】:

  • 您所说的“不可预测性和不一致”具体是什么意思?系统是否遇到实际的数据不一致问题和竞争条件?您的服务当前如何访问数据库 - 嵌入式 SQL 查询、ORM 或存储过程?
  • @allen-smithee 谢谢,这些都是很好的问题。是的,DB 和比赛条件的不一致是一个问题。死锁很多。目前他们正在使用嵌入式 SQL 查询。我宁愿不使用存储过程来解决这个问题。我喜欢在主存储库中管理我的查询。

标签: c# database architecture


【解决方案1】:

1/ 数据访问层只是简单地封装了数据逻辑,您需要的是concurrency control,以确保您的数据模型在独立服务之间的一致性。

2/ 根据您实现并发的方式,它可能是单点故障,但我认为这没有什么问题——“故障计划”是一个很好的设计理念。您可以构建冗余和故障转移机制,也可以将并发控制分布在您的服务中。

3/ 您选择实现并发的方式将取决于您的应用程序如何运行以及您的用户期望什么。给出一些具体的场景:

场景 A

当服务开始更新时,启动事务并为所涉及的记录取出一个或多个行级锁。如果任何其他服务尝试同时编辑记录,则阻止或返回错误,例如“此记录当前已锁定”。请注意,必须在读取之前获取所有锁,并在更新期间保留所有锁,以确保与其他写入保持一致。

优点 - 为小型数据模型实施相当简单。 MSSQL 支持大量锁定方案,甚至可以使用自定义application locks 对资源进行分组。

缺点 - 如果您的事务需要访问多个表/行并且不同的服务或函数访问重叠的表,您很容易陷入各种死锁问题。 MSSQL 通常更喜欢悲观锁定,并且可以将锁从行升级到页和表级别,这意味着读取和写入锁的行为方式可能与您最初不期望的方式不同。您可能需要花费大量时间在 SQL Server Profiler 中调试这些交互,并准备好更改您的数据模型以解决这些问题。

场景 B

每个表行都有一个递增的版本号。服务读取它需要的数据,执行一系列更新,然后在事务锁中检查当前行版本与它用于更新的行版本。如果版本号不匹配,它会回滚事务,取消更新。然后服务可能会尝试从读取数据开始再次执行该操作。

优点 - 读取器不会被阻止,并且在服务尝试提交更新时锁定只是非常短暂的。 MSSQL 以具有“快照隔离”级别的“行版本控制”的形式内置了对这种并发方法的支持。如果冲突很少见,此方法可以非常灵敏 - 非常适合实时应用程序。

缺点 - 此方法可能需要对您的数据模型和服务行为进行重大更改。

场景 C

单个数据服务负责所有数据访问。其他服务向该服务请求数据并提交更新。该服务负责读取和写入数据库和文件系统,并执行一定程度的数据完整性检查并解决数据冲突。

优点 - 将数据完整性和控制封装在一个模块中,从而简化其他服务。允许您在应用程序级别实现缓存、锁定等,提供更细粒度的控制。

缺点 - 需要对现有架构进行重大更改。如果您选择在字段级别解决数据冲突,则可能需要大量代码。当无法解决时,服务需要能够处理被拒绝的更新。


这是我能想到的主要场景,但还有很多。一般来说,所有数据的并发控制都将围绕执行操作时的锁定(悲观锁定);执行一个动作,然后检查冲突(通过版本控制乐观锁定);或执行一项操作,然后合并冲突(冲突解决)。

考虑您的特定数据模型以及模型的更新方式将指导您将使用这些技术的哪种组合。搜索上面的任何术语都会给您带来大量阅读内容,并且有很多 Technet 文章专门解决了 MSSQL 上下文中的这些问题。振作起来 - 我见过优秀的程序员犯了这个错误,这确实是一个具有挑战性的问题,但如果你有条不紊地解决它是可以解决的。

【讨论】:

  • 谢谢,这是一个很好的答案。我可能会尝试场景 C,因为我还希望能够从一个地方管理逻辑(现在在不同的服务中都有复杂功能的精确副本)。这也将增加可扩展性和可管理性。我将围绕这个解决方案搜索一些最佳实践。
猜你喜欢
  • 2016-05-19
  • 1970-01-01
  • 2018-08-16
  • 1970-01-01
  • 1970-01-01
  • 2017-11-18
  • 1970-01-01
  • 2010-11-25
  • 1970-01-01
相关资源
最近更新 更多