草庐IT

mysql - 做数据库事务防止其他用户干扰它

coder 2023-10-08 原文

假设我这样做(注意:下面的语法可能不正确,但不要担心......它只是为了说明一点)

Start Transaction
INSERT INTO table (id, data) VALUES (100,20), (100,30);
SELECT * FROM table WHERE id = 100;
End Transaction

因此 select 的目标是从表中获取所有信息,这些信息只是通过前面的插入插入的,并且只能通过前面的 INSERT...

现在假设在执行期间,在执行 INSERT 之后,其他一些用户也执行了 id = 100 的 INSERT ...

事务下一步中的 SELECT 语句是否也会获取其他用户执行的 INSERT 插入的行,还是只获取事务中前面的 INSERT 插入的两行?

顺便说一句,我正在使用 MySQL,所以请根据 MySQL 定制你的答案

最佳答案

这完全取决于数据库连接使用的事务隔离。

根据 MySQL 5.0 Certification Study Guide

第 420 页描述了隔离级别处理的三种事务条件

  • 脏读是一个事务读取另一个事务未提交的更改。假设事务 T1 修改了一行。如果事务 T2 读取该行并看到修改,即使 T1 尚未提交它,这就是脏读。这是一个问题的原因之一是,如果 T1 回滚,更改将被撤消,但 T2 不知道。
  • 当事务执行两次相同的检索但每次都得到不同的结果时,就会发生不可重复读取。假设 T1 读取一些行,然后 T2 更改其中一些行并提交更改。如果 T1 在再次读取行时看到更改,它会得到不同的结果;初始读取是不可重复的。这是一个问题,因为 T1 无法从同一查询中获得一致的结果。
  • 幻像是出现在之前不可见位置的行。假设T1和T2开始,T1读取了一些行。如果 T2 插入一个新行并且 T1 在再次读取时看到该行,则该行是幻像。

第 421 页描述了四 (4) 个事务隔离级别:

  • READ-UNCOMMITTED :允许事务查看其他事务所做的未提交更改。此隔离级别允许脏读、不可重复读和幻读发生。
  • READ-COMMITTED :允许事务仅在其他事务已提交时查看其他事务所做的更改。未提交的更改仍然不可见。此隔离级别允许发生不可重复读取和幻像。
  • REPEATABLE READ (默认):确保事务发出相同的 SELECT 两次,两次都得到相同的结果,而不管其他事务所做的已提交或未提交的更改。换句话说,它从同一查询的不同执行中获得一致的结果。在一些数据库系统中,REPEATABLE READ 隔离级别允许幻象,这样如果另一个事务插入新行,在 SELECT 语句之间的中间,第二个 SELECT 将看到它们。 InnoDB 并非如此; REPEATABLE READ 级别不会出现幻影。
  • SERIALIZABLE :将一项交易的影响与其他交易完全隔离。它类似于 REPEATABLE READ,但有一个额外的限制,即在第一个事务完成之前,一个事务选择的行不能被另一个事务更改。

可以在全局、 session 内或特定事务中为您的数据库 session 设置隔离级别:

SET GLOBAL TRANSACTION ISOLATION LEVEL isolation_level;
SET SESSION TRANSACTION ISOLATION LEVEL isolation_level;
SET TRANSACTION ISOLATION LEVEL isolation_level;

其中 isolation_level 是以下值之一:

  • '读取未提交'
  • '读取已提交'
  • '可重复读取'
  • '可序列化'

my.cnf 中你也可以设置默认值:

[mysqld]
transaction-isolation = READ-COMMITTED

关于mysql - 做数据库事务防止其他用户干扰它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13938194/

有关mysql - 做数据库事务防止其他用户干扰它的更多相关文章

  1. ruby - 其他文件中的 Rake 任务 - 2

    我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时

  2. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  3. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  4. ruby - 我可以使用 aws-sdk-ruby 在 AWS S3 上使用事务性文件删除/上传吗? - 2

    我发现ActiveRecord::Base.transaction在复杂方法中非常有效。我想知道是否可以在如下事务中从AWSS3上传/删除文件:S3Object.transactiondo#writeintofiles#raiseanexceptionend引发异常后,每个操作都应在S3上回滚。S3Object这可能吗?? 最佳答案 虽然S3API具有批量删除功能,但它不支持事务,因为每个删除操作都可以独立于其他操作成功/失败。该API不提供任何批量上传功能(通过PUT或POST),因此每个上传操作都是通过一个独立的API调用完成的

  5. ruby-on-rails - 使用 rails 4 设计而不更新用户 - 2

    我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它​​不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数

  6. ruby - Ruby 有 `Pair` 数据类型吗? - 2

    有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳

  7. ruby-on-rails - 简单的 Ruby on Rails 问题——如何将评论附加到用户和文章? - 2

    我意识到这可能是一个非常基本的问题,但我现在已经花了几天时间回过头来解决这个问题,但出于某种原因,Google就是没有帮助我。(我认为部分问题在于我是一个初学者,我不知道该问什么......)我也看过O'Reilly的RubyCookbook和RailsAPI,但我仍然停留在这个问题上.我找到了一些关于多态关系的信息,但它似乎不是我需要的(尽管如果我错了请告诉我)。我正在尝试调整MichaelHartl'stutorial创建一个包含用户、文章和评论的博客应用程序(不使用脚手架)。我希望评论既属于用户又属于文章。我的主要问题是:我不知道如何将当前文章的ID放入评论Controller。

  8. ruby - 调用其他方法的 TDD 方法的正确方法 - 2

    我需要一些关于TDD概念的帮助。假设我有以下代码defexecute(command)casecommandwhen"c"create_new_characterwhen"i"display_inventoryendenddefcreate_new_character#dostufftocreatenewcharacterenddefdisplay_inventory#dostufftodisplayinventoryend现在我不确定要为什么编写单元测试。如果我为execute方法编写单元测试,那不是几乎涵盖了我对create_new_character和display_invent

  9. ruby - RVM "ERROR: Unable to checkout branch ."单用户 - 2

    我在新的Debian6VirtualBoxVM上安装RVM时遇到问题。我已经安装了所有需要的包并使用下载了安装脚本(curl-shttps://rvm.beginrescueend.com/install/rvm)>rvm,但以单个用户身份运行时bashrvm我收到以下错误消息:ERROR:Unabletocheckoutbranch.安装在这里停止,并且(据我所知)没有安装RVM的任何文件。如果我以root身份运行脚本(对于多用户安装),我会收到另一条消息:Successfullycheckedoutbranch''安装程序继续并指示成功,但未添加.rvm目录,甚至在修改我的.bas

  10. ruby - 分布式事务和队列,ruby,erlang,scala - 2

    我有一个涉及多台机器、消息队列和事务的问题。因此,例如用户点击网页,点击将消息发送到另一台机器,该机器将付款添加到用户的帐户。每秒可能有数千次点击。事务的所有方面都应该是容错的。我以前从未遇到过这样的事情,但一些阅读表明这是一个众所周知的问题。所以我的问题。我假设安全的方法是使用两阶段提交,但协议(protocol)是阻塞的,所以我不会获得所需的性能,我是否正确?我通常写Ruby,但似乎Redis之类的数据库和Rescue、RabbitMQ等消息队列系统对我的帮助不大——即使我实现某种两阶段提交,如果Redis崩溃,数据也会丢失,因为它本质上只是内存。所有这些让我开始关注erlang和

随机推荐