Sql事务的并发处理

2024-01-24

假设我要使用 ASP.NET 和 SQL Server 2005 启动一个项目。我必须设计该应用程序的并发要求。我计划在每个表中添加一个时间戳列。在更新表时,我将检查时间戳列是否与所选的相同。

这种方法足够吗?或者这种方法在任何情况下都有缺点吗?

请指教。

Thanks

Lijo


首先,我认为您在问题中描述的方式最好的办法用于以 MS SQL 作为数据库的 ASP.NET 应用程序。数据库中没有锁定。与它完美搭配永久断开连接的客户端就像网络客户端一样。

如何从一些答案中解读,术语中存在误解。我们都指使用 Microsoft SQL Server 2008 或更高版本来保存数据库。如果您在 MS SQL Server 2008 文档中打开主题“rowversion (Transact-SQL)”,您将发现以下内容:

"时间戳是的同义词行版本数据类型并受 数据类型同义词的行为。”... “这时间戳语法已弃用。 此功能将在 Microsoft SQL 的未来版本 服务器。避免在以下情况中使用此功能 新的开发工作,并计划 修改当前使用的应用程序 此功能。”

So 时间戳数据类型是同义词行版本MS SQL 的数据类型。它保存 64 位计数器,该计数器存在于每个数据库内部,可以看作@@DBTS。在数据库的一张表中修改一行后,计数器将增加。

当我读到你的问题时,我读到“TimeStamp”作为该类型的列名行版本数据。我个人更喜欢这个名字行更新时间戳。在 AzManDB(请参阅 Microsoft Authorization Manager with the Store as DB)中,我可以看到这样的名称。有时也被使用子更新时间戳追踪层次结构行更新时间戳结构(关于触发器)。

我在上一个项目中实现了这种方法,并且非常高兴。一般来说,您会执行以下操作:

  1. Add 行更新时间戳p 列到数据库中每个表的类型行版本(它将在 Microsoft SQL Management Studio 中显示为时间戳,这是相同的)。
  2. 您应该构建所有 SQL SELECT 查询以将结果发送到客户端,以便您发送额外的结果行版本值与主要数据一起。如果你有一个带 JOINT 的 SELECT,你应该发送行版本最大的行更新时间戳两个表中的值,例如
SELECT s.Id AS Id
    ,s.Name AS SoftwareName
    ,m.Name AS ManufacturerName
    ,CASE WHEN s.RowUpdateTimeStamp > m.RowUpdateTimeStamp
          THEN s.RowUpdateTimeStamp 
          ELSE m.RowUpdateTimeStamp 
     END AS RowUpdateTimeStamp 
FROM dbo.Software AS s
    INNER JOIN dbo.Manufacturer AS m ON s.Manufacturer_Id=m.Id

或者进行如下数据转换

SELECT s.Id AS Id
    ,s.Name AS SoftwareName
    ,m.Name AS ManufacturerName
    ,CASE WHEN s.RowUpdateTimeStamp > m.RowUpdateTimeStamp
          THEN CAST(s.RowUpdateTimeStamp AS bigint)
          ELSE CAST(m.RowUpdateTimeStamp AS bigint)
     END AS RowUpdateTimeStamp 
FROM dbo.Software AS s
    INNER JOIN dbo.Manufacturer AS m ON s.Manufacturer_Id=m.Id

to hold 行更新时间戳 as bigint,对应于ulongC# 的数据类型。如果您从许多表创建 OUTER JOINT 或 JOINT,则构造MAX(RowUpdateTimeStamp)从所有表中都会看到有点复杂。由于 MS SQL 不支持 MAX(a,b,c,d,e) 等函数,因此相应的构造可能如下所示:

(SELECT MAX(rv)
 FROM (SELECT table1.RowUpdateTimeStamp AS rv
      UNION ALL SELECT table2.RowUpdateTimeStamp
      UNION ALL SELECT table3.RowUpdateTimeStamp
      UNION ALL SELECT table4.RowUpdateTimeStamp
      UNION ALL SELECT table5.RowUpdateTimeStamp) AS maxrv) AS RowUpdateTimeStamp
  1. 所有断开连接的客户端(Web 客户端)不仅接收并保存某些数据行,而且行版本 (type ulong) 的数据行。
  2. 在一次尝试修改来自断开连接的客户端的数据时,您的客户端应该发送行版本对应于服务器的原始数据。这spSoftwareUpdate存储过程可能看起来像
CREATE PROCEDURE dbo.spSoftwareUpdate
    @Id int,
    @SoftwareName varchar(100),
    @originalRowUpdateTimeStamp bigint, -- used for optimistic concurrency mechanism
    @NewRowUpdateTimeStamp bigint OUTPUT
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    -- ExecuteNonQuery() returns -1, but it is not an error
    -- one should test @NewRowUpdateTimeStamp for DBNull
    SET NOCOUNT ON;

    UPDATE dbo.Software
    SET Name = @SoftwareName
    WHERE Id = @Id AND RowUpdateTimeStamp <= @originalRowUpdateTimeStamp

    SET @NewRowUpdateTimeStamp = (SELECT RowUpdateTimeStamp
                                  FROM dbo.Software
                                  WHERE (@@ROWCOUNT > 0) AND (Id = @Id));
END

Code of dbo.spSoftwareDelete存储过程看起来是一样的。如果你不开机NOCOUNT,你可以产生DB并发异常在很多场景中自动生成。 Visual Studio 为您提供了使用乐观并发的可能性,例如高级选项中的“使用乐观并发”复选框TableAdapter or DataAdapter.

如果你看dbo.spSoftwareUpdate细心的你会发现,我使用的存储过程RowUpdateTimeStamp <= @originalRowUpdateTimeStamp在 WHERE 而不是RowUpdateTimeStamp = @originalRowUpdateTimeStamp。我这样做是因为,@originalRowUpdateTimeStamp其客户端通常被构造为MAX(RowUpdateTimeStamp)来自多个表格。所以可能是这样RowUpdateTimeStamp < @originalRowUpdateTimeStamp。要么你应该使用严格平等=并在此处重现与 SELECT 语句中使用的相同的复杂 JOIN 语句或使用<=像我一样构建并保持与以前一样的安全。

顺便说一句,人们可以为ETag基于 RowUpdateTimeStamp,它可以在 HTTP 标头中与数据一起发送到客户端。随着ETag您可以在客户端实现智能数据缓存。

我无法在这里编写完整的代码,但是你可以在互联网上找到很多示例。我只想再重复一次,在我看来,使用基于乐观并发的方法行版本 is 适用于大多数 ASP.NET 场景的最佳方法.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Sql事务的并发处理 的相关文章

  • 混合语言源目录布局

    我们正在运行一个使用多种不同语言的大型项目 Java Python PHP SQL 和 Perl 到目前为止 人们一直在自己的私有存储库中工作 但现在我们希望将整个项目合并到一个存储库中 现在的问题是 目录结构应该是什么样的 我们应该为每种
  • Oracle 获取列值发生变化的行

    假设我有一张桌子 比如 ID CCTR DATE 1 2C 8 1 2018 2 2C 7 2 2018 3 2C 5 4 2017 4 2B 3 2 2017 5 2B 1 1 2017 6 UC 11 23 2016 还有其他字段 但我
  • 在 plsql 中立即执行

    如何从这段代码中得到结果 EXECUTE IMMEDIATE SELECT FROM table name through for loop 通常的方法看起来像这样 for items in select from this table l
  • 整理有关 QueryDSL-JPA 的提示

    有没有办法用 QueryDSL 来执行它 粗体部分 从地点选择 其中名称如 cafe 整理 Latin1 general CI AI 我将 JPA 与 hibernate 一起使用 您可以使用addFlag QueryFlag Positi
  • 仅当变量不为空时 SQL 添加过滤器

    您好 我有疑问如下 SELECT route id ROUTE ID FROM route master NOLOCK WHERE route ou 2 AND route query l s query AND lang id 1 这里
  • 在同一个表上组合两个 SQL SELECT 语句

    我想结合这两个 SQL 查询 SELECT FROM Contracts WHERE productType RINsell AND clearTime IS NULL AND holdTime IS NOT NULL ORDER BY g
  • Scala 中用于阻止调用的 Future

    The Akka文档说 you may be tempted to just wrap the blocking call inside a Future and work with that instead but this strate
  • 是否允许在流水线 PL/SQL 表函数中使用 SELECT?

    管道函数的文档指出 在 SQL 语句 通常是SELECT 并且在大多数示例中 管道函数用于数据生成或转换 接受客户作为参数 但不发出任何 DML 语句 现在 从技术上讲 可以使用 SELECT 而不会出现 Oracle 中的任何错误 ORA
  • 在 Postgres 中的数组字段上应用聚合函数?

    是否可以对整数 字段 或其他数字数组 中的所有值应用聚合 如 avg stddev CREATE TABLE widget measurement integer insert into widget measurement values
  • 如何通过循环变量在 dbt 中多次运行 SQL 模型?

    我有一个 dbt 模型 测试模型 接受地理变量 zip state region 在配置中 我想通过循环变量来运行模型三次 每次使用不同的变量运行它 问题是 我有一个如下所示的宏 它将变量附加到输出表名称的末尾 即运行测试模型 with z
  • Yii 查询时对相关模型的限制

    我遇到了极限问题 我正在使用的代码如下 model PostCategory model record model gt with array posts gt array order gt posts createTime DESC li
  • 通过将行旋转为动态数量的列来在 MySQL 中创建摘要视图

    我在 MySQL 中有一个表 其中包含以下字段 id company name year state 同一客户和年份有多行 以下是数据示例 id company name year state 1 companyA 2008 1 2 com
  • 与 FOREIGN KEY 约束冲突

    我有两张桌子 学术界 CREATE TABLE dbo R ACADEMIE ID ACADEMIE dbo IDENTIFIANT NOT NULL LC ACADEMIE CODE dbo LIBELLE COURT NOT NULL
  • 这是过滤数据并防止 SQL 注入和其他攻击的安全方法吗?

    我创建了两个简单的函数来在插入数据进入 mysql 查询之前对其进行过滤 对于表单字段 我还使用正则表达式来单独检查每个字段 Form filter function filter var HTML is not allowed var s
  • ORA-01749: 您不能向自己授予/撤销权限

    我正在运行以下查询RATOR MONITORING授予引用权限的架构RATOR MONITORING CONFIGURATION SMSC GATEWAY表到RATOR MONITORING schema GRANT REFERENCES
  • 使用 xmlagg 时出现子查询错误和太多值

    我在连接许多大型表中的所有数据时遇到问题 我昨天对此提出了问题 但不幸的是 listagg 似乎不是一个好的选择 链接子查询返回多行 https stackoverflow com questions 54651144 subquery r
  • 使用 Powershell SQL 将数据提取到 Excel

    我想使用 powershell 将数据从 SQL Server 提取到新的 excel 文件 对于小型数据集 我的代码可以工作 但某些表的行数超过 100 000 行 这将需要很长时间 我不在 SQl 服务器中使用该实用程序的原因是因为我想
  • 将此 MySQL 查询转换为 PyGreSQL

    我正在开发一个 Ruby 应用程序 它使用 mysql 函数 XOR 和 BIT COUNT 不过 我现在需要在运行 PyGreSQL 的 Heroku 上运行该应用程序 我找不到任何可以帮助我的 PyGreSQL 文档 那么任何人都可以翻
  • SQLite 条件 ORDER BY 中的 DESC

    我需要选择按以下逻辑排序的记录 但是当 DESC 处于条件中时 SQLite 会引发错误 ORDER BY CASE WHEN parentGUID IS NULL THEN datePosted DESC ELSE datePosted
  • 如何将 SQL“LIKE”与 LINQ to Entities 结合使用?

    我有一个文本框 允许用户指定搜索字符串 包括通配符 例如 Joh Johnson mit ack on 在使用 LINQ to Entities 之前 我有一个存储过程 该存储过程将该字符串作为参数并执行以下操作 SELECT FROM T

随机推荐

  • Vim 正则表达式将 unicode 字符与非单词匹配

    我有以下文字 y 以下正则表达式搜索与字符 匹配 W Vim 正则表达式中有 unicode 标志吗 不幸的是 还没有这样的标志 一些内置字符类 可以 包括多字节字符 其他人则不然 常见的 w a l u类仅包含 ASCII 字母 因此即使
  • MySQL“无法在 FROM 子句中指定更新目标表”背后的基本原理

    在 MySQL 中 如果我正在执行一个谓词 则无法在谓词中重用表DELETE or UPDATE在同一张桌子上 例如 这是不可能的 DELETE FROM story category WHERE category id NOT IN de
  • 我可以跳过证书验证 oracle utl_http 吗?

    我正在 pl SQL 中开发一些连接到多个外部服务的应用程序 Example declare utl req utl http req utl resp utl http resp begin This line in production
  • 编译后未创建 libphp5.so 且未创建前缀目录

    configure with apxs2 usr local apache bin apxs prefix usr local apache php with config file path usr local apache php ma
  • JHipster 按实体字段搜索实体

    我有锦标赛实体 他与奖项实体具有 OneToOne 关系 获奖实体已备案 金额 因此 如果我想搜索在两个值之间有奖品的锦标赛 我该如何使用 JHipster QueryService 来做到这一点 基于您正在使用 QueryService
  • 为什么属性目标“typevar”没有记录?

    众所周知 在 C 中可以指定target自定义属性规范 如示例所示 method SomeDecoration return SomeOtherMark int MyMethod 目标 在哪里method and return 帮助指定属性
  • 等待函数到底如何针对条件变量工作

    背景 我对条件变量如何与共享数据的并发访问结合使用的理解有些困惑 以下是描述我当前问题的伪代码 Thread 1 Producer void cakeMaker lock some lock while number of cakes MA
  • 如何修复 .net 标准 2.0 项目中的“无法加载文件或程序集 System.IO.Packaging,版本=4.0.3.0”

    我正在尝试处理一个word文档 为此 我安装了 DocumentFormat OpenXml NuGet 包 它安装了以下依赖项 文档格式 OpenXml 系统 IO 封装 4 5 0 系统 运行时 序列化 一旦它到达我正在处理Word文档
  • C++ 转换重载函数时遇到问题:<未解析的重载函数类型>

    我在超类中有一些函数 旨在将字符串与内部函数相关联 class Base typedef std function
  • 如何从字符串输入中删除逗号

    我正在开发一个使用 MIPS 本机指令的程序 该程序将允许用户输入三个十进制数字作为空终止字符串 每个数字不能超过六位数字 如果用户输入逗号 例如 123 456 则从内存中删除逗号 第一个数字存储在内存地址 0x10000000 中 第二
  • 如何在 Symfony 中添加新的翻译域

    我正在使用 symfony 在我的包中我需要创建一些翻译 但我宁愿在与 消息 不同的域中进行操作 就像 FOS User Bundle 所做的那样 他们使用 FOSUserBundle 域 所以我用我的翻译创建了一个 MyBundle en
  • ReactNative Flatlist - Flatlist 项的优化性能

    当我们有大数据时如何优化 Flatlist 的性能 我的列表既有图像又有文字描述 我想找到一种方法来提高列表的性能并删除从缓存列表中加载的额外图像以及让清单不重 FlatList 组件应该是一个高性能的解决方案 用于在应用程序中显示大量数据
  • Java框架[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 最近 我遇到了许多用 Java 创建 Web 应用程序的不同框架 例如 Play Wicket Gra
  • Xcode 中的 Boost 库编译器错误

    如何在 Xcode 中正确使用 boost 我正在尝试使用 boost 库编译一个项目 该示例项目在终端中使用 GCC 12 可以正常编译 但我无法在 Xcode 中编译它 编译器错误主要是 boost 库中的命名空间问题 例如 boost
  • -[UITextField isFirstResponder] 即使字段当前正在编辑也会返回 false

    在我的视图控制器中 viewDidLoad方法 我调用 myTextField becomeFirstResponder 这就像一个魅力 打开键盘 myTextField 获得焦点 我有一个带有目标操作的按钮 该操作位于同一控制器中 用于检
  • Bash:如何将这两个 if 语句压缩为一个

    我是 Bash 和脚本新手 我想找到一种方法将这两个语句合并为 1 该脚本的作用是检查两个文件 D1 和 D2 是否是同一文件 如果不是 则检查它们的内容是否相同 if D1 ef D2 then echo not the same fil
  • 在 Electron 中操作 DOM

    在电子应用程序中操作 DOM 的最佳方法是什么 我使用 ipc 和 webcontents 从文档中制作了一些教程 但没有运气 我的应用程序非常简单 我只想像控制台一样使用网络并显示来自多个同步函数 主过程 结果的消息 渲染过程 我用真实的
  • 如何制作“查看密码”?

    我正在制作密码识别系统 我想做一个 查看密码 功能 可以切换隐藏到显示密码 我不知道如何实现这个功能 这是我的简短代码 from tkinter import root Tk Entry box to get password from u
  • UICollectionView - 滚动到第一个单元格

    我正在使用 UICollectionView 单击按钮后需要滚动到第一个单元格 该按钮位于我的集合视图中的 大 标题部分 单击它时 我需要滚动到位于该按钮下方的第一个单元格 我创建了此按钮的操作 但我不知道如何滚动到第一个 UICollec
  • Sql事务的并发处理

    假设我要使用 ASP NET 和 SQL Server 2005 启动一个项目 我必须设计该应用程序的并发要求 我计划在每个表中添加一个时间戳列 在更新表时 我将检查时间戳列是否与所选的相同 这种方法足够吗 或者这种方法在任何情况下都有缺点