一、数据库事务Transactions
1.为什么要使用事务
事务可以让数据库保持一致性,通过事务的机制恢复到某个时间点,即使系统崩溃数据库修改的数据不会丢失。
2.存储引擎支持事务的情况
命令: show engines;
只有InnoDB支持事务
3.事务基本概念
事务:一组逻辑操作单元,使数据从一种状态变换为另一种状态。比如有一组增删改操作,要么全部成功,要么全部失败,整体的。
事务处理的原则:保证所有的事务都是一个工作单元执行,即使出现故障,也能恢复到某个时间点。当一个事务进行多个操作,所有事务提交commit,修改永久保存下来。要么放弃,事务回滚rollback到最初状态
转账案例:
4.事务的ACID特性
①原子性
原子性是事务的一个不可分割的单位(整体性),要么全部提交commit,要么全部失败回滚rollback。
②一致性
一致性是指事务执行前后,数据从一个合法性状态变换为另一个合法性状态。合法性是业务逻辑合法,符合现实世界的约束,满足这个约束就是合法状态。在事务中某个操作失败,系统撤销当前的事务,返回事务之前的状态。自己定义的规则
举例1:
A账户200,转账300出去,此时账户-100。这个状态就不合法,余额>=0
举例2:
A账户200,转账50给B账户,A扣钱了,但是由于故障B余额没有增加。状态不合法,A+B余额不变。
③隔离性
事务的隔离性是指一个事务的执行不能被其他事务干扰,一个事务对数据进行操作,此时的数据对并发的其他事务是隔离的。各个事务之间互不干扰。
④持久性
持久性是指事务一旦提交,数据库数据的改变是永久性的。
持久性是通过事务日志保证的,日志包括重做日志和回滚日志。
重做日志:通过事务对数据进行修改时候,把数据库变化信息记录到重做日志。然后进行修改。即使系统故障。数据库重启找到重做日志,重新执行使事务由持久性。
5.事务的状态
①活动的
事务对应的数据库操作正在执行过程中时,还在对数据库进行增删改,该事务处在活动状态。
②部分提交的
事务的操作完成了,但操作在内存执行,还没有刷新到磁盘。此时就是部分提交的状态。
③失败的
事务在活动的或部分提交状态时,出现故障错误,此时是失败的。
④中止的
当事务失败时,进行回滚到恢复数据库之前的状态。
⑤提交的
部分提交的状态时,然后同步到磁盘上。事务提交的状态。
二、如何使用事务
事务有2种:显式事务和隐式事务
1.显示事务—手动提交
①开启事务start transaction;或begin;
②一系列DML操作
③结束状态:事务提交commit,回滚事务rollback to [savepoint]
保存点savepoint:事务中设置一个标志,用来标记事务的执行的某个位置,这个位置之前都可以回滚
④begin
一系列DML操作
commit
这是一个事务。
2.隐式事务—自动提交
①查看数据库事务自动提交的状态
SHOW VARIABLES LIKE 'autocommit';
②开启事务自动提交
SET autocommit = ON;
③关闭事务自动提交
SET autocommit = OFF;
④自动提交事务,每一条增删改就是一个事务。
3.隐式(自动)提交事务的情况
①对数据库,表,视图,存储过程进行create,alter,drop时。会自动提交语句之前的事务
②当修改数据库的表时,会自动提交语句之前的事务
③当使用手动提交事务start transaction或begin会自动提交之前事务。当系统变量autocommit调为ON自动提交事务。
三、事务的举例:提交与回滚,只有InnoDB支持
前提开启事务自动提交
set autocommit=on;
情况一:
结果只有:张三
情况二:
结果是:张三,李四
情况三:
所以只有张三
情况四:
四、数据并发问题与4种隔离级别
1.数据并发出现的问题
①脏写update:更新失效,两个事务同时更新
当两个事务同时去更新某一条数据时,就肯定存在一前一后。当事务A更新时,还没有提交。事务B也过来更新,事务A覆盖了事务B更新的数据,这就是脏写。脏写导致数据丢失。
②脏读:读取到还没提交的数据
如果一个事务B向数据库更新数据,事务还没提交或终止。另一个事务A查询到了B还没提交的数据。这是脏读。
③不可重复读:两次读取内容不一样
有事务A对这行数据进行查询,此时事务B对这个数据进行了修改。事务A再次查询这个数据,发现两次读取的值不同。
④幻读:插入或删除记录
事务A查询数据表有多少行数,此时的事务B对这个数据表进行增加或删除记录。此时事务A再次查询,莫名其妙的发现数据记录遗失或增多。
严重性: 脏写 > 脏读 > 不可重复读 > 幻读
2.SQL的四种隔离级别
①READ UNCOMMITTED:未提交读。所有事务能查询到其他事务未提交的执行结果。
②READ COMMITTED:已提交读。一个事务只能看到已提交事务的执行结果
③REPEATABLE READ:可重复读。事务A在读取一条数据之后,事务B对该数据进行修改并提交,事务A再次读取数据,读取到的还是原来内容(MySQL默认)
④SERIALIZABLE:可串行化。事务持续期间。禁止其他事务对这个表进行操作。性能低下
3.MySQL支持的四种隔离级别
①查看当前MySQL的隔离级别
MySQL5.7版本之前:SELECT @@tx_isolation;
MySQL5.7版本之后:SELECT @@transaction_isolation;
默认是REPEATABLE-READ,可重复读
②设置MySQL的隔离级别:
SET [GLOBAL|SESSION] TRANSACTION_ISOLATION = '隔离级别'
#其中,隔离级别格式:
> READ-UNCOMMITTED
> READ-COMMITTED
> REPEATABLE-READ
> SERIALIZABLE
③设置隔离级别global和session的影响
global:全局范围有效。对已存在的会话无效,只对设置后新的会话有效。
session:当前会话有效。对当前会话的后续事务有效。