mysql中如何实现事务隔离级别

分类:编程技术 时间:2024-02-20 15:25 浏览:0 评论:0
0
本文介绍如何在MySQL中实现事务隔离级别。内容非常详细。有兴趣的朋友可以参考一下。希望对大家有所帮助。

事务是一组一起成功或一起失败的 SQL 语句。事务还应该具有原子性、一致性、隔离性和持久性。

1.事务的基本要素(ACID)

1.原子性:事务启动后,所有操作要么成功,要么失败,这是不可能的。在中间状态下,交易是一个不可分割的整体,就像一个原子。

2.一致性:事务开始和结束前后,不违反数据库的完整性约束。 A转账给B,A扣了钱,B却没有收到。

3.隔离性:同时事务(concurrent transactions)不应该导致数据库处于不一致的状态。每笔交易独立执行,不影响交易结果是否存在其他交易。

4.持久性:事务对数据库所做的更改将保存在磁盘上并且不会丢失。

2.事务并发问题

1.脏读:事务A读取了事务B未提交的写入数据,读到的数据称为脏数据

2。不可重复读:事务A多次读取相同的数据,但在读取过程中,事务B修改了数据并提交。结果,相同的数据被多次读取,结果不同。

3.幻读:事务A修改了表中的所有数据行,比如设置status = 1,但同时事务B向表中插入了一行status = 0的新数据。对于操作事务 对于用户A来说,表中还有一条记录没有被修改,就像幻觉一样。

3.四级事务隔离

< /tr>< td>读取已提交读取已提交
Transact离子隔离级别脏读不可重复读幻读
读未提交读未提交

×

< h2>√
可重复读取

×

×< /h2>

可序列化

×

×

×

4.获取和设置数据库隔离级别

SHOW VARIABLES LIKE '%isolation%';SHOW GLOBAL VARIABLES LIKE '%isolation%';

使用系统变量查询

SELECT @@GLOBAL.tx_isolation;SELECT @@SESSION.tx_isolation;SELECT @@tx_isolation;

对于mysql8,使用以下变量进行查询

SELECT @@GLOBAL.transaction_isolation;SELECT @@SESSION.transaction_isolation;SELECT @@transaction_isolation;

设置隔离级别

SET GLOBAL tx_isolation = '隔离级别';SET SESSION tx_isolation = '隔离级别';SET @@tx_isolation = '隔离级别';

对于mysql8,使用如下语句设置

SET GLOBAL transaction_isolation = '隔离级别';SET SESSION transaction_isolation = '隔离级别';SET @@transaction_isolation = '隔离级别';

5.通过例子解释各个隔离级别

首先准备一个表和一些数据。

创建表 `account` ( `id` int(11) unsigned NOT NULL AUTO_INCRMENT COMMENT 'ID', `name` varchar(32) DEFAULT '' COMMENT 'name ', `money` 小数(11,2) DEFAULT '0.00' COMMENT 'Money', PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;INSERT INTO `account` (`name`, `money`) VALUES ('A', '500.00');INSERT INTO `account` (`name`, `money`) VALUES ('B', '100.00');

1.读取未提交

set transaction_isolation = 'READ-UNCOMMITTED';set autocommit = 0;

事务B修改了表中的数据,但未提交,事务A确认修改的数据被读取。如果事务B由于某种原因回滚,那么事务A读到的数据就是脏数据。

2.读提交

set transaction_isolation = 'READ-COMMITTED';set autocommit = 0;

事务B修改数据但不提交,那么事务A仍然获取到原始数据,解决了脏读问题。

但是事务B提交,事务A执行上一次查询,结果与上一次查询不一致,导致不可重复读问题。

3.可重复读取

set transaction_isolation = 'REPEATABLE-READ';set autocommit = 0;

事务B修改了数据并提交了。事务A的两次查询结果是一致的,这说明解决了不可重复读取的问题。

此时,交易A修改了名为A的钱数据。

名为A的钱变成了350,而不是400,可以重复读取,保证数据一致性。

我们将交易A中所有账户的资金重新修改为200,同时在交易B中插入一条新的数据。

事务A仍然获取两条数据,解决了新增数据时事务A的幻读问题。

4.序列化

set transaction_isolation = 'SERIALIZABLE';set autocommit = 0;

< p>事务A查询表,如果如果没有提交,事务B的insert语句就会在那里等待,直到超时或者事务A提交。

反之,事务B插入表但未提交后,事务A对该表的查询也会等到事务B提交。

此时,表wi读写表时会被锁定。当然,对并发性能的影响也会比较大。

隔离级别越高,可以保证数据越完整和一致。

6. MySQL锁

锁分为两种类型:

内部锁:内部锁由MySQL服务器内部执行,用于管理多个会话中表内容的争用。

外部锁:MySQL为客户端会话提供显式获取表锁的功能,以防止其他会话访问该表。

内部锁有两种类型:

1。行级锁:行级锁是细粒度的。只有被访问的行才会被锁定,这允许多个会话同时进行写访问。

2.表级锁:MySQL 对 myisam、内存和合并表使用表级锁,一次只允许一个会话更新表,这使得这些存储引擎更适合基于读的操作操作。

外部锁:可以使用LOCK TABLE和UNLOCK TABLE来控制锁定。

READ(共享锁):多个会话可以从表中读取数据,而无需获取锁。此外,多个会话可以获取同一个表上的锁。当 READ 锁定时,没有会话可以向表写入数据。任何写操作都将等待 READ 锁被释放。

WRITE(独占锁):当表被WRITE锁定时,除了持有该锁的会话之外,任何其他会话都不能读取或写入数据,除非释放WRITE锁。

锁定表的语句:

LOCK TABLES table_name [READ | WRITE];

解锁表的语句:

p>
UNLOCK TABLES;

锁定数据库中的所有表:

使用读锁刷新表; 

我在这里分享一下如何在mysql中实现事务隔离级别。希望以上内容能够对大家有所帮助大家都可以学到更多的知识。如果您觉得文章不错,可以分享出去,让更多的人看到。

1. 本站所有资源来源于用户上传或网络,仅作为参考研究使用,如有侵权请邮件联系站长!
2. 本站积分货币获取途径以及用途的解读,想在本站混的好,请务必认真阅读!
3. 本站强烈打击盗版/破解等有损他人权益和违法作为,请各位会员支持正版!
4. 编程技术 > mysql中如何实现事务隔离级别

用户评论