当前位置: 首页 > 面试题库 >

SQL原子增量和锁定策略-这样安全吗?

慕容嘉荣
2023-03-14
问题内容

我对SQL和锁定策略有疑问。例如,假设我在我的网站上有一个图片计数器。如果我有一个sproc或类似的东西来执行以下语句:

START TRANSACTION;
UPDATE images SET counter=counter+1 WHERE image_id=some_parameter;
COMMIT;

假设在时间t0特定image_id的计数器的值为‘0’。如果两个会话从t0同时开始更新同一个图像计数器s1和s2,则这两个会话都有可能都读取值‘0’,将其增加为‘1’,并且都尝试将计数器更新为‘1
‘,那么计数器将获得值‘1’而不是‘2’?

s1: begin
s1: begin
s1: read counter for image_id=15, get 0, store in temp1
s2: read counter for image_id=15, get 0, store in temp2
s1: write counter for image_id=15 to (temp1+1), which is 1 
s2: write counter for image_id=15 to (temp2+1), which is also 1
s1: commit, ok
s2: commit, ok

最终结果:image_id = 15的错误值“ 1”应为2。

我的问题是:

  1. 这种情况可能吗?
  2. 如果是这样,事务隔离级别是否重要?
  3. 是否有一个冲突解决程序可以将这种冲突检测为错误?
  4. 可以使用任何特殊的语法来避免出现问题(例如“比较并交换”(CAS)或显式锁定技术)吗?

我对一般答案感兴趣,但是如果没有答案,我会对MySql和InnoDB特定的答案感兴趣,因为我试图使用此技术在InnoDB上实现序列。

编辑:以下情况也有可能,导致相同的行为。我假设我们处于隔离级别READ_COMMITED或更高,因此s2从事务开始就获取了值,尽管s1已经将‘1’写入了计数器。

s1: begin
s1: begin
s1: read counter for image_id=15, get 0, store in temp1
s1: write counter for image_id=15 to (temp1+1), which is 1 
s2: read counter for image_id=15, get 0 (since another tx), store in temp2
s2: write counter for image_id=15 to (temp2+1), which is also 1
s1: commit, ok
s2: commit, ok

问题答案:

UPDATE 查询将更新锁放置在页面或读取的记录上。

当决定是否更新记录时,该锁将被解除或提升为排他锁。

这意味着在这种情况下:

s1: read counter for image_id=15, get 0, store in temp1
s2: read counter for image_id=15, get 0, store in temp2
s1: write counter for image_id=15 to (temp1+1), which is 1 
s2: write counter for image_id=15 to (temp2+1), which is also 1

s2将等待直到s1决定是否写入计数器,并且这种情况实际上是不可能的。

会是这样的:

s1: place an update lock on image_id = 15
s2: try to place an update lock on image_id = 15: QUEUED
s1: read counter for image_id=15, get 0, store in temp1
s1: promote the update lock to the exclusive lock
s1: write counter for image_id=15 to (temp1+1), which is 1 
s1: commit: LOCK RELEASED
s2: place an update lock on image_id = 15
s2: read counter for image_id=15, get 1, store in temp2
s2: write counter for image_id=15 to (temp2+1), which is 2

请注意,在中InnoDBDML查询不会从其读取的记录中提取更新锁。

这意味着在全表扫描的情况下,已读取但决定不更新的记录将一直保持锁定状态,直到事务结束,并且无法从另一个事务更新。



 类似资料:
  • 主要内容:命令配置密码,手动配置密码,指令安全,端口安全,SSH代理Redis 提供了诸多安全策略,比如为了保证数据安全,提供了设置密码的功能。Redis 密码设置主要有两种方式:一种是使用 命令来设置密码;另外一种则是手动修改 Redis 的配置文件。虽然看似前者更为简单,其实两种方式各有特点。本节将对它们进行介绍。 命令配置密码 通过执行以下命令查看是否设置了密码验证: 在默认情况下 requirepass 参数值为空的,表示无需通过密码验证就可以连接到 Re

  • 在这个世界上没有绝对的安全,我们说这台服务器安全并不是说它绝对不会有安全风险,不会受到损害。只能说明该台服务器的安全可信度高,不易受到侵害。相反,如果我们说这台服务器不安全,即可信度低,则这台服务器可能是一些服务的配置有安全漏洞或没有做数据冗余。每种环境、每种应用的可信度要求是有不同的,不能一概而论,如作为企业中心数据库服务器的可信度要求就比内部WEB服务器的可信度要求高。需投入更多的资金和时间对

  • PodSecurityPolicy 类型的对象能够控制,是否可以向 Pod 发送请求,该 Pod 能够影响被应用到 Pod 和容器的 SecurityContext。 查看 Pod 安全策略建议 获取更多信息。 什么是 Pod 安全策略? Pod 安全策略 是集群级别的资源,它能够控制 Pod 运行的行为,以及它具有访问什么的能力。 PodSecurityPolicy对象定义了一组条件,指示 Po

  • 本文向大家介绍什么是安全策略?相关面试题,主要包含被问及什么是安全策略?时的应答技巧和注意事项,需要的朋友参考一下 回答:安全策略是一个正式且简短的计划,其中包含组织的目标,目的和信息安全程序。简而言之,它定义了确切地需要保护免受威胁的条件以及在威胁发生时如何处理情况。

  • 内容安全策略 CSP(Content Security Policy)即内容安全策略,主要目标是减少、并有效报告 XSS 攻击,其实质就是让开发者定制一份白名单,告诉浏览器允许加载、执行的外部资源。即使攻击者能够发现可从中注入脚本的漏洞,由于脚本不在白名单之列,浏览器也不会执行该脚本,从而降低客户端遭受 XSS 攻击风险。 默认配置下,CSP 甚至不允许执行内联代码 (<script> 块内容,内

  • CSP(内容安全策略) CSP(Content Security Policy) 即内容安全策略,主要目标是减少、并有效报告 XSS 攻击,其实质就是让开发者定制一份白名单,告诉浏览器允许加载、执行的外部资源。即使攻击者能够发现可从中注入脚本的漏洞,由于脚本不在白名单之列,浏览器也不会执行该脚本,从而达到了降低客户端遭受 XSS 攻击风险和影响的目的。 默认配置下,CSP 甚至不允许执行内联代码