事务的基本概念
谈到事务,首先要谈到事务的ACID机制 ,ACID包括原子性,一致性,隔离性和永久性.原子性,分别概述一下这四个概念
原子性
要么全部成功,要么全部失败
一致性
一致性是指事务执行前后的状态是相同的,指的是事务执行的前后状态符合现实世界的合法性状态
隔离性
事务不被外部并发的事务干扰
永久性
一旦事务执行完毕,即永久保存
事务的状态
事务的状态: 活动的(正在进行),部分提交(没有刷写到磁盘里面),失败的,中止的,提交的(数据的安全性由事务日志保障)
事务的分类
事务分为显式事务和隐式事务,显式事务是指显式声明 begin或者start transaction,隐式事务是指对表进行的DML(表数据)或者DDL(表结构)操作,会自动进行事务提交,如何设置事务的官网链接 开启事务的方式 begin和start transaction(推荐),使用commit 提交
begin 和 start transaction的区别
begin 是 start transaction 的别名,start transaction允许添加后缀,支持 read only ,read write 和read consistent snapshot 事务
开启read only
只允许读数据
开启 read write
允许读和修改数据
开启read consistent snapshot
这个东西比较复杂,先上官网的解释
A consistent read means that InnoDB uses multi-versioning to present to a query a snapshot of the database at a point in time. The query sees the changes made by transactions that committed before that point in time, and no changes made by later or uncommitted transactions. The exception to this rule is that the query sees the changes made by earlier statements within the same transaction. This exception causes the following anomaly: If you update some rows in a table, a SELECT sees the latest version of the updated rows, but it might also see older versions of any rows. If other sessions simultaneously update the same table, the anomaly means that you might see the table in a state that never existed in the database. If the transaction isolation level is REPEATABLE READ (the default level), all consistent reads within the same transaction read the snapshot established by the first such read in that transaction. You can get a fresher snapshot for your queries by committing the current transaction and after that issuing new queries.
具体的翻译如下
一致读取意味着 InnoDB 使用多版本控制向查询呈现数据库在某个时间点的快照。查询会看到在该时间点之前提交的事务所做的更改,以及稍后或未提交的事务所做的更改。此规则的例外是查询会看到同一事务中先前语句所做的更改。此异常会导致以下异常:如果您更新表中的某些行,则 SELECT 会看到更新行的最新版本,但它也可能会看到任何行的旧版本。如果其他会话同时更新同一个表,则异常意味着您可能会看到该表处于数据库中从未存在过的状态。如果事务隔离级别为 REPEATABLE READ(默认级别),则同一事务中的所有一致性读取都会读取该事务中第一次此类读取所建立的快照。您可以通过提交当前事务并在此之后发出新查询来获得查询的更新快照。
并发问题
1 脏写
事务a修改了未提的事务b提交的数据
2 脏读
事务a读取事务b未提交且回滚的数据
3 不可重复读
事务a读取事务b修改前后的数据不同
4 幻读
事务a读取事务b增删前后的数据
事务隔离级别
READ UNCOMMITTED:读未提交,在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。不能避免脏读、不可重复读、幻读。
READ COMMITTED:读已提交,它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)。可以避免脏读,但不可重复读、幻读问题仍然存在。
REPEATABLE READ:可重复读,事务A在读到一条数据之后,此时事务B对该数据进行了修改并提交,那么事务A再读该数据,读到的还是原来的内容。可以避免脏读、不可重复读,但幻读问题仍然存在。这是MySQL的默认隔离级别。
SERIALIZABLE:可串行化,确保事务可以从一个表中读取相同的行。在这个事务持续期间,禁止其他事务对该表执行插入、更新和删除操作。所有的并发问题都可以避免,但性能十分低下。能避免脏读、不可重复读和幻读。
#查看隔离级别
SHOW VARIABLES LIKE 'transaction_isolation';
#设置
SET [GLOBAL|SESSION] TRANSACTION_ISOLATION = '隔离级别'#其中,隔离级别格式:> READ-UNCOMMITTED
> READ-COMMITTED
> REPEATABLE-READ
> SERIALIZABLE
事务的分类
mysql事务日志
mysql事务日志包括redo log 和undo log 日志,redo日志(记录数据库的修改的行为)保证了事务的持久性,undo日志保证了事务的原子性(提供了历史版本,可撤回)
redo日志
redo日志的工作流程,将记录刷写到log里面,由master线程去处理刷写到数据库里面
redo日志包括redo bufffer 和redo file,redo先将数据刷写到redo buffer(内存)后再将数据写入redo file(持久化)
#查看系统缓存
show variables like '%innodb_log_buffer_size%';
redo log 的刷盘策略
刷盘策略为一
刷盘策略为二
刷盘策略为0
undo日志
记录一个事务的多个版本,提供事务的多个版本的回滚操作