mysql事务所_MySQL 事务

事务是一组原子性的SQL操作,确保数据一致性。ACID属性包括原子性、一致性、隔离性和持久性。MySQL提供四种隔离级别:读未提交、提交读、可重复读和可串行化,以平衡并发和数据一致性。可重复读是MySQL默认级别,通过MVCC避免幻读。死锁是事务处理中的问题,而事务日志提高了效率。MySQL的InnoDB引擎支持事务,自动提交是默认模式。
摘要由CSDN通过智能技术生成

事务是一组原子性的 SQL 查询,或者说一个独立的工作单元。如果数据库引擎能够成功地对数据库应用该组查询的全部语句,那么就执行该组查询。如果其中任何一条语句因为崩溃或其他原因无法执行,那么所有的语句都不会执行。也就是说,事务内的语句,要么全部执行成功,要么全部执行失败。

ACID 表示原子性 (atomicity)、一致性(consistency)、隔离性(isolation)和持久性(durability)。一个运行良好的事务处理系统,必须具备这些标准特征。

原子性(atomicity)

一个事务必须被视为一个不可分割的最小单元,整个事务中的所有操作要么全部提交成功,要么全部失败回滚,对于一个事务而言,不可能只执行其中的一部分操作,这就是事务的原子性。

一致性(consistency)

数据库总是从一个一致性的状态转换到另一个一致性的状态。

隔离性(isolation)

通常来说,一个事务所做的修改在最终提交之前,对其他事务是不可见的。

持久性(durability)

一旦事务提交,则其所做的修改就会永久保存在数据库中。

隔离级别

隔离性其实比想象的要复杂。在 MySQL 标准中定义了四种隔离级别,每一种级别都规定了一个事务中所做的修改,哪些在事务内和事务外是可见的,哪些是不可见的。较低级别的隔离通常可以执行更高的并发,系统的开销也更低。

下面简单介绍一下四种隔离级别。

READ UNCOMMITED (未提交读)

在 READ UNCOMMITED 级别,事务中的修改,即使没有提交,对其他事务也是可见的。事务可以读取未提交的数据,这也被称为脏读(Dirty Read)。这个级别会导致很多问题,从性能问题上来讲,READ UNCOMMITED 不会被其他的级别好太多,但是缺乏其他级别的好处,在实际应用中一般很少用到。

READ COMMITED(提交读)

大多数数据库系统的默认隔离级别都是 READ COMMITED (但 MySQL 不是)。READ  COMMITED 满足前面提到的隔离性的简单定义:一个事务开始时,只能“看见”已经提交的事务所做的修改。换句话说,一个事务 从开始到提交之前,所做的任何修改对其他事务都是不可见的。这个级别有时候也被称为不可重复读(nonrepeatable read),因为两次执行相同的查询,可能会得到不一样的结果。

REPEATABLE READ(可重复读)

REPEATABLE READ 解决了脏读的问题。该级别保证了在同一个事务中多次读取同样记录的结果是一样的。但是理论上,可重复读隔离级别还是无法解决另外一个幻读(Phantom Read)问题。所谓幻读,指的是当某个事务在读取某个范围内的记录时,另外一个事务也在该范围内插入了一条新的记录,当之前的事务再次读取该范围的记录时,会产生幻行(Phantom Row)。InnoDB 和 XtraDB 存储引擎通过多版本并发控制(MVCC)解决了幻读的问题。

可重复读是 MySQL 默认的事务隔离级别。

SERIALIZABLE (可串行化)

SERIALIZABLE 是最高的隔离级别,它通过强制事务串行执行,避免前面所说的幻读问题。简单来说,SERIALIZABLE 会在读取每一行数据上都加锁,所以可能导致大量的超时和锁争用的问题。

ANSI SQL 隔离级别:

隔离级别

脏读可能性

不可重复读可能性

幻读可能性

加锁读

READ UNCOMMITED

Yes

Yes

Yes

No

READ COMMITED

No

Yes

Yes

No

REPEATABLE READ

No

No

Yes

No

SERIALZABLE

No

No

No

Yes

死锁

死锁是指两个事务或者多个事务在同一资源的相互占用,并请求锁定对方占用的资源。从而导致恶性循环的现象。当多个事务试图以不同的顺序锁定资源时,就可能会产生死锁。

为了解决这个问题,数据库系统实现了各种死锁检测和死锁超时机制。

锁的行为和顺序是和存储引擎有关的。以相同的顺序执行语句,有些存储引擎会产生死锁,有些则不会。

事务日志

事务日志可以帮助提高事务的效率。使用事务日志,存储引擎在修改表时只需要修改其内存拷贝,再把该修改行为记录到持久在硬盘上的事务日志中,而不是每次都把修改的数据本身持久到磁盘上。事务日志采用的是追加的方式,因此写日志的操作是磁盘上一小块区域内的顺序 I/O,而不像随机 I/O 需要在磁盘的多个地方移动磁头,所以采用事务日志的方式相对来说要快得多。

MySQL 中的事务

MySQL 提供了两种事务型的存储引擎:InnoDB 和 NDB Cluster。

自动提交(AUTOCOMMIT)

MySQL 默认采用自动提交(AUTOCOMMIT)模式。也就是说,如果不是显式地开始一个事务,则每个查询都会被当做一个事务执行提交操作。在当前连接中,可以通过设置 AUTOCOMMIT 变量来启用或禁用自动提交模式。

mysql > set AUTOCOMMIT = 1;

1或者 ON 表示启用,0或者 OFF 表示禁用。当 AUTOCOMMIT = 0 时,所有的查询都是在一个是事务中,直到显式的执行 COMMIT 提交或者 ROLLBACK 回滚,该事务结束。同时又开始了另一个新事务。修改 AUTOCOMMIT 对非事务型的表,比如 MyISAM 或者内存表,不会有任何影响。对这类表来说,没有 COMMIT 或者 ROLLBACK 的概念,也可以说是相当于一直处于 AUTOCOMMIT 启用的模式。

在事务中混合使用存储引擎

MySQL 服务层不管理事务,事务是由下层的存储引擎实现的。所以在同一个事务中,使用多种存储引擎是不可靠的。

如果在事务中混合使用了事务型和非事务型的表(例如 InnoDB 和 MyISAM 表),在正常提交的情况下不会有任何问题,但如果该事务需要回滚,非事务表上的变更是无法撤销的。所以,为每张表选择合适的存储引擎非常重要。

隐式和显示锁定

InnoDB 采用的两阶段锁定协议(two-phase locking protocol)。在事务执行过程中,随时都可以执行锁定,锁只有在执行 COMMIT 和 ROLLBACK 的时候才会释放,并且所有的锁都是在同一时刻被释放。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值