我有一些使用 PHP 和 MySQL 的经验,并且我了解事务,但使用它们的经验相当少。
我正在开发一个 Web 应用程序,用户将在其中对单个数据库进行/执行各种 CRUD 操作。 (是的,它是 InnoDB)。我很好奇交易的行为方式,我会给你一个相当简单的例子:
1.) 用户 1 开始一个事务,将我的数据库中的 John Smith 的名称更新为 Johnathon Smith。
2.) 用户 2 开始一项交易以读取 John Smith 的姓名紧接在用户 1 的交易开始之后,但在此之前已提交。
用户 2 会看到什么结果? John 还是 Johnathon?
用户1在交易过程中,John Smith的记录是被锁定了,还是交易过程中可以读取?
此外,这两个交易的时间安排如何?用户 2 的交易是否坐在某个队列中等待用户 1 的交易完全完成? MySQL 数据库如何对试图访问同一表/记录的多个事务进行分类?
另外,假设用户 1 的交易操作平均需要 500 毫秒才能完成,而用户 2 的交易操作平均需要 750 毫秒才能完成。用户 2 的响应时间有多长? 1250 毫秒?
非常感谢任何指向相关文章或其他 SO 问题的链接!
最佳答案
它的默认工作方式是用户 2 看到 John Smith,直到用户 1 提交并且用户 2 开始新事务。 p>
换句话说,默认事务隔离称为可重复读取。也就是说,InnoDB 假设用户 2 希望看到用户 2 开始其当前事务时的数据库。即使其他人更新数据并提交他们的更新,用户 2 仍然希望看到原始数据,直到他明确刷新他的数据库“ View ”。
MySQL 解决这个问题的方法是保留更新行的两个版本。 Johnathon Smith 的“当前”版本有一个指向该行先前版本的内部指针。 InnoDB 将检查这些版本,确定用户 2 是否应该能够看到当前版本,如果不能,则按照指向先前版本的指针。这是逐行自动完成的。
用户 2 的交易根本没有理由等待,这就是“读者不会阻止写入者,反之亦然”的意思。这就是多版本并发控制 (MVCC) 功能的好处,它在许多 RDBMS 产品中都有类似的实现,例如 Oracle、PostgreSQL 和 Firebird。
一旦用户 1 提交了他的更改,并且没有仍在运行的事务需要查看该行的先前版本,InnoDB 就会有一个后台线程逐渐清理那些旧版本。
这很重要,例如对于想要运行多个查询并且希望所有小计匹配的报告应用程序。如果报告中的后一个查询看到了一个稍微更新的数据库 View ,它们可能会得到与前一个查询不同的结果。
您可以选择将事务隔离级别更改为 READ-COMMITTED,这样用户 2 将自动不断刷新他的数据库“ View ”,以查看更新后的名称 Johnathon Smith(原文如此)但是仅在用户 1 提交后。如果用户 1 尚未提交,则用户 2 无法看到更改。
您甚至可以将事务隔离级别更改为 READ-UNCOMMITTED,这样用户 2 甚至可以在用户 1 提交之前看到更新。但这很少是您想要做的——用户 1 可以回滚,因为 Johnathon 显然是 Jonathan 的拼写错误。
您可以尝试自己测试所有这些,方法是打开两个运行 mysql 客户端的 shell 窗口,并在它们之间来回跳转,看看更改如何从一个 session 到另一个 session 可见。
您将想要了解如何使用 SET TRANSACTION更改每个 session 的事务隔离级别的语句。
另见:
关于php - MySQL 事务时序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21176435/
我发现ActiveRecord::Base.transaction在复杂方法中非常有效。我想知道是否可以在如下事务中从AWSS3上传/删除文件:S3Object.transactiondo#writeintofiles#raiseanexceptionend引发异常后,每个操作都应在S3上回滚。S3Object这可能吗?? 最佳答案 虽然S3API具有批量删除功能,但它不支持事务,因为每个删除操作都可以独立于其他操作成功/失败。该API不提供任何批量上传功能(通过PUT或POST),因此每个上传操作都是通过一个独立的API调用完成的
我有一个涉及多台机器、消息队列和事务的问题。因此,例如用户点击网页,点击将消息发送到另一台机器,该机器将付款添加到用户的帐户。每秒可能有数千次点击。事务的所有方面都应该是容错的。我以前从未遇到过这样的事情,但一些阅读表明这是一个众所周知的问题。所以我的问题。我假设安全的方法是使用两阶段提交,但协议(protocol)是阻塞的,所以我不会获得所需的性能,我是否正确?我通常写Ruby,但似乎Redis之类的数据库和Rescue、RabbitMQ等消息队列系统对我的帮助不大——即使我实现某种两阶段提交,如果Redis崩溃,数据也会丢失,因为它本质上只是内存。所有这些让我开始关注erlang和
文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co
我看到其他人也遇到过类似的问题,但没有一个解决方案对我有用。0.3.14gem与其他gem文件一起存在。我已经完全按照此处指示完成了所有操作:https://github.com/brianmario/mysql2.我仍然得到以下信息。我不知道为什么安装程序指示它找不到include目录,因为我已经检查过它存在。thread.h文件存在,但不在ruby目录中。相反,它在这里:C:\RailsInstaller\DevKit\lib\perl5\5.8\msys\CORE\我正在运行Windows7并尝试在Aptana3中构建我的Rails项目。我的Ruby是1.9.3。$gemin
我已经开始使用mysql2gem。我试图弄清楚一些基本的事情——其中之一是如何明确地执行事务(对于批处理操作,比如多个INSERT/UPDATE查询)。在旧的ruby-mysql中,这是我的方法:client=Mysql.real_connect(...)inserts=["INSERTINTO...","UPDATE..WHEREid=..",#etc]client.autocommit(false)inserts.eachdo|ins|beginclient.query(ins)rescue#handleerrorsorabortentirelyendendclient.commi
保存成功后可以回滚吗?让我有一个带有属性名称、电子邮件等的用户模型。例如u=User.newu.name="test_name"u.email="test@email.com"u.save现在记录将成功保存在数据库中,之后我想回滚我的事务(不是销毁或删除)。有什么想法吗? 最佳答案 您可以通过交易来做到这一点,请参阅http://markdaggett.com/blog/2011/12/01/transactions-in-rails/例子:User.transactiondoUser.create(:username=>'Nemu
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。我来自C、php和bash背景,很容易学习,因为它们都有相同的C结构,我可以将其与我已经知道的联系起来。然后2年前我学了Python并且学得很好,Python对我来说比Ruby更容易学。然后从去年开始,我一直在尝试学习Ruby,然后是Rails,我承认,直到现在我还是学不会,讽刺的是那些打着简单易学的烙印,但是对于我这样一个老练的程序员来说,我只是无法将它
我正在尝试绕过rails配置这个极其复杂的迷宫。到目前为止,我设法在ubuntu上设置了rvm(出于某种原因,ruby在ubuntu存储库中已经过时了)。我设法建立了一个Rails项目。我希望我的测试项目使用mysql而不是mysqlite。当我尝试“rakedb:migrate”时,出现错误:“!!!缺少mysql2gem。将其添加到您的Gemfile:gem'mysql2'”当我尝试“geminstallmysql”时,出现错误,告诉我需要为安装命令提供参数。但是,参数列表很大,我不知道该选择哪些。如何通过在ubuntu上运行的rvm和mysql获取rails3?谢谢。
我目前正在上一门数据库类(class),其中一个实验室问题让我困惑于如何实现上述内容,事实上,如果可能的话。我试过搜索docs但是定义的交易方式比较模糊。这是我第一次尝试在没有Rails的情况下进行任何数据库操作,所以我有点迷茫。我已经成功地创建了一个到我的postgresql数据库的连接并且可以执行语句,我需要做的最后一件事是根据一个简单的条件回滚一个事务。请允许我向您展示代码:require'pg'@conn=PG::Connection.open(:dbname=>'db_15_11_labs')@conn.prepare('insert','INSERTINTOhouse(ho
如何使用Rails中的事务block一次性更新/保存模型的多个实例?我想更新数百条记录的值;每条记录的值都不同。这不是一个属性的批量更新情况。Model.update_all(attr:value)在这里不合适。MyModel.transactiondothings_to_update.eachdo|thing|thing.score=rand(100)+rand(100)thing.saveendendsave似乎发布了它自己的事务,而不是将更新分批处理到周围的事务中。我希望所有更新都在一次大交易中进行。我怎样才能做到这一点? 最佳答案