一、什么是事务隔离?
事务隔离是指在数据库中,多个并发执行的事务之间相互隔离的程度。事务隔离级别是一个重要的概念,它定义了事务在读取和修改数据时能够接触到其他事务所做的修改的程度。
事务隔离的目的是确保并发事务能够正确地执行,同时保持数据库的一致性和可靠性。在一个并发环境中,多个事务可能同时读取和修改数据库中的数据,如果没有适当的隔离机制,会出现一些问题,如脏读、不可重复读和幻读。
什么是脏读
脏读(Dirty Read):一个事务读取了另一个未提交事务所做的修改的数据。如果这个未提交的事务最终回滚,那么读取到的数据就是无效的。脏读可能导致不一致性和错误的结果。
举例说明:
事务A读取数据,并在此期间事务B修改了这些数据,但事务B最终回滚了。如果事务A读取了事务B未提交的修改,那么事务A读取到的数据是脏数据。
什么是不可重复读
一个事务在同一查询中两次读取同一行数据时,得到了不同的结果。这是因为在两次读取之间,其他事务修改了被读取的数据。
举例说明:
事务A读取了一行数据,然后事务B修改了该行数据,并提交了事务B。如果事务A再次读取相同的行,它将得到不同的结果,这导致事务A无法重复读取一致的数据。
什么是幻读
一个事务在同一查询中两次执行,得到了不同的行数。这是因为在两次查询之间,其他事务插入或删除了符合查询条件的数据。
举例说明:
事务A执行了一次查询,返回一组结果。然后事务B插入了符合相同查询条件的新数据,并提交了事务B。如果事务A再次执行相同的查询,它将得到不同的行数,这导致了幻读现象。
二、MySql的事务隔离级别
MySQL 提供了四个事务隔离级别,分别是读未提交(Read Uncommitted)、读已提交(Read Committed)、可重复读(Repeatable Read)和串行化(Serializable)。这些隔离级别定义了事务在读取和修改数据时能够接触到其他事务所做的修改的程度,各自具有不同的特点和并发控制机制。
读未提交(Read Uncommitted)
在这个隔离级别下,事务可以读取其他事务尚未提交的修改。这意味着可能出现脏读、不可重复读和幻读等问题。读未提交是最低的隔离级别,并发性能较高,但数据的一致性和可靠性较差,通常不建议使用。
读已提交(Read Committed)
在这个隔离级别下,事务只能读取其他事务已经提交的修改。这解决了脏读的问题,但仍然可能出现不可重复读和幻读。读已提交提供了较好的并发性能和一定的数据一致性,是许多数据库默认的隔离级别。
可重复读(Repeatable Read)
在这个隔离级别下,事务在第一次读取数据后会创建一个一致性视图,并在事务结束之前始终使用这个视图。这意味着事务内部的查询不会受到其他事务的修改影响,解决了不可重复读的问题。但幻读仍然可能发生,即在同一查询中,事务可能看到其他事务插入或删除的数据。
串行化(Serializable)
在这个隔离级别下,事务是完全串行执行的,每个事务在执行期间都会对数据进行加锁,避免了脏读、不可重复读和幻读等问题。但是串行化会对并发性能产生严重影响,因为它需要对数据进行较强的加锁,限制了并发访问。
三、MySql设置和修改事务隔离级别
MySQL 的默认事务隔离级别是 REPEATABLE READ
(可重复读)
使用
SET TRANSACTION ISOLATION LEVEL
语句可以在当前会话中设置事务隔离级别。语法如下:SET TRANSACTION ISOLATION LEVEL
其中, 可以是
READ UNCOMMITTED
、READ COMMITTED
、REPEATABLE READ
或 SERIALIZABLE
。
例如,要将当前会话的事务隔离级别设置为可重复读(REPEATABLE READ):
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
设置成功后,该会话执行的后续事务将使用指定的隔离级别。
如果需要设置 MySQL 数据库的全局默认事务隔离级别,可以通过修改配置文件来实现。
找到 MySQL 配置文件 my.cnf
(Windows 系统上可能命名为 my.ini
),在其中的 [mysqld]
段落中添加或修改以下行:
transaction-isolation =
其中, 同样可以是
READ UNCOMMITTED
、READ COMMITTED
、REPEATABLE READ
或 SERIALIZABLE
。
保存并关闭配置文件后,重启 MySQL 服务使新的全局隔离级别生效。