数据库事务是否阻止其他用户干扰它

pil*_*ght 4 mysql sql database transactions

假设我这样做(注意:下面的语法可能不正确,但不要担心它...它只是在那里提出一个观点)

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

因此,select的目标是从刚刚插入的表中获取所有信息,并且仅由前面的INSERT插入...

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

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

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

Rol*_*DBA 6

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

根据MySQL 5.0认证学习指南

在此输入图像描述

页面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不是这样; 重复读取级别不会出现幻像.
  • SERIALIZABLE:完全隔离一个交易与其他交易的影响.它与REPEATABLE READ类似,附加限制是在第一个事务完成之前,一个事务选择的行不能被另一个事务更改.

可以在全局,会话内或特定事务中为数据库会话设置隔离级别:

SET GLOBAL TRANSACTION ISOLATION LEVEL isolation_level;
SET SESSION TRANSACTION ISOLATION LEVEL isolation_level;
SET TRANSACTION ISOLATION LEVEL isolation_level;
Run Code Online (Sandbox Code Playgroud)

其中isolation_level是以下值之一:

  • 'READ UNCOMMITTED'
  • 'READ COMMITTED'
  • 'REPEATABLE READ'
  • 'SERIALIZABLE'

my.cnf你可以设置默认的还有:

[mysqld]
transaction-isolation = READ-COMMITTED
Run Code Online (Sandbox Code Playgroud)