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

mysql中的并行事务

双俊人
2023-03-14
问题内容

我的数据库包含名为的表,该表sample_table由名为的一列组成,user_first_name并且该表为空

假设我有2笔这样的交易

START TRANSACTION;
INSERT INTO sample_table VALUES("TEJA");
INSERT INTO sample_table VALUES("TEJA");
INSERT INTO sample_table VALUES("TEJA");
INSERT INTO sample_table VALUES("TEJA");
INSERT INTO sample_table VALUES("TEJA");
INSERT INTO sample_table VALUES("TEJA");
INSERT INTO sample_table VALUES("TEJA");
//......... till 10000 times
COMMIT

START TRANSACTION;
SELECT * FROM sample_table;
SELECT * FROM sample_table;
SELECT * FROM sample_table;
SELECT * FROM sample_table;
SELECT * FROM sample_table;
SELECT * FROM sample_table;
//........ till 10000 times 
COMMIT

我以这种方式并行运行这两个事务,首先运行transaction1,然后在运行transaction1时运行transaction2。我希望结果将包含一些名称为TEJA的行。但是我得到了一个空洞的结果。请帮助我解释为什么结果为空?


问题答案:

这完全取决于ISOLATION LEVEL您设置的。

您可以看到使用此查询设置了哪一个:

select @@global.tx_isolation, @@session.tx_isolation;

在解释不同的隔离级别之前,让我解释一下他们试图避免哪些问题:

  • 脏读 :一个尚未完成交易的数据被另一个事务读取。

  • 丢失更新 :两个事务修改表中的并行条目。当两个事务完成时,仅应用一个修改。

  • 不可重复读 :读Reoccuring导致不同的结果。

  • 幻读 :一个事务其他事务添加,删除或修改表条目在。

现在针对不同的隔离级别。

读未提交
使用此隔离级别,读操作将忽略任何类型的锁,因此可能发生上述任何问题。

已提交读
此隔离级别为应修改的对象的整个事务设置了写锁定。读取锁仅在读取数据时设置。因此,可能发生不可重复的读取和幻像读取。

重复读取
通过这种隔离级别,可以确保当参数相同时,重复发生的读取操作始终会产生相同的结果。在事务的总持续时间内,为读写操作设置了锁定。因此,只能进行幻像读取。

可序列化
最高的隔离级别确保并行运行的事务的结果与事务将一个接一个地运行的结果相同。大多数数据库并没有真正一个接一个地运行这些事务,这会造成性能损失。因此,可能发生一项事务中止的情况。例如,MySQL通过MVCC(多版本并发控制)实现了这一点。如果您想了解更多,请使用Google。这个答案太多了。

此表中的所有内容也对此进行了解释:

                 | Lost updates | Dirty Read | Non-Repeatable Read | Phantom Read
---------------------------------------------------------------------------------
Read Uncommitted | possible     | possible   | possible            | possible
Read Committed   | impossible   | impossible | possible            | possible
Repeatable Read  | impossible   | impossible | impossible          | possible
Serializable     | impossible   | impossible | impossible          | impossible
  • 在本手册中,有更多有关它以及如何设置隔离级别的信息。


 类似资料:
  • 我有相同的模块,连接数据库运行在两个服务器(后台和前台)。它与同一个数据库连接。 我使用JPA(Hibernate实现)和Spring事务管理。 我有以下问题: 我必须用两个不同字段的最大值1更新表a中的字段a(表a中的字段a,表b中的字段b) 案例1: 更新前 表A fA = 100 tableB fB=102 更新后 表a fA=103 tableB fB=102 案例2: 更新前 表A fA

  • 问题内容: 最近,在一个用于mysql数据库的PHP脚本中,我需要在恰好位于另一个事务内部的某个位置使用事务。我所有的测试似乎都表明这很好,但是我找不到有关此用法的任何文档。 我想确定-交易中的交易在mysql中是否有效?如果是这样,是否有办法找出嵌套事务中的层数?(即恢复到正常状态需要多少回滚) 预先感谢,Brian 问题答案: 手册的本页可能使您感兴趣: 12.3.3。 导致隐性提交的陈述 ;

  • 问题内容: 我正在遍历多个值(例如1到100),并在循环内执行准备好的语句。 与在循环内直接执行相比,使用事务(在循环结束后提交)有优势吗? 这些值并不相互依赖,因此从该角度来看不需要进行事务处理。 问题答案: 如果您的查询是INSERT,请参见第7.2.19页。MySQL手册中INSERT语句的速度给出了两个有趣的信息,这取决于您是否使用事务引擎: 使用非事务引擎时: 要加快对非事务性表使用多个

  • 我使用嵌套的Select语句从表1中获得单行结果,我需要在同一行的末尾追加表3中的另一列(COLX)。我试过联合,但结果是两行。有什么建议吗? table2.colz和table3.colx是用来匹配条目的ID。这两个最终结果都符合要求。 编辑(进一步解释我的表结构) COLX是表3的ID,以匹配表2中的COLZ 表2 ID中的COL1与表1中的COL1匹配 结果我需要的是表1.col1,表1.c

  • 问题内容: 我的存储过程的基本结构是 MySQL版本: 5.1.61-0ubuntu0.11.10.1-log 当前,如果“查询2”失败,则提交“查询1”的结果。 如果任何查询失败,如何回滚事务? 问题答案: 看看http://dev.mysql.com/doc/refman/5.0/en/declare- handler.html 基本上,您声明错误处理程序,它将调用回滚

  • 本文向大家介绍讲解MySQL中的事务特性,包括了讲解MySQL中的事务特性的使用技巧和注意事项,需要的朋友参考一下 一个事务是一个连续的一组数据库操作,就好像它是一个单一的工作单元进行。换言之,永远不会是完整的事务,除非该组内的每个单独的操作是成功的。如果在事务的任何操作失败,则整个事务将失败。 实际上,会俱乐部许多SQL查询到一个组中,将执行所有的人都一起作为事务的一部分。 事务的特性: 事务有