MySQL事务与隔离级别的使用基础理论
绿仔牛奶_ 人气:0什么是事务
事务就是一组操作的集合,事务将整组操作作为一个整体,共同提交或者共同撤销
这些操作只能同时成功或者同时失败,成功即可提交事务,失败就执行事务回滚
MySQL的事务默认是自动提交的,一条语句执行成功,MySQL将会隐式的提交事务
以转账为例,张三向李四转账1000元
这个整体行为包含三个操作:首先查询张三账户的余额,其次将张三账户余额-1000,最后将李四账户余额+1000。事务就是将这三个操作看作最小提交单元,就是一荣俱荣一损俱损。
-- 查看事务管理状态 1-自动 0-手动 select @@autocommit; -- 设置事务手动管理 set @@autocommit = 0; -- 开启事务 start transaction; -- 开启事务:start transaction 或者 begin select money from account where name = '张三'; update account set money = money - 1000 where name = '张三'; update account set money = money + 1000 where name = '李四'; -- 事务提交 commit; -- 事务回滚 rollback;
事务四大特性ACID
原子性Atomicity:一组操作为最小执行单元,只能全部执行成功或者全部失败
一致性Consistency:事务完成后,所有数据都要保持一致状态
一致性表示事务完成后,数据操作前后符合逻辑运算,状态一致
隔离性Isolation:是指在并发操作数据库时,各个事务之间不会相互影响
持久性Durability:事务一旦提交或回滚,对于数据库的修改将会永久保存
并发事务问题
脏读
两个事务A和B在并发下操作数据库中的同一数据时,当事务A对数据进行了修改但是还没有commit的同时,事务B对该数据进行了select,此时事务B读取到的数据就是不准确的。这种情况叫做脏读
事务B读取到了事务A修改但还未提交的数据---->脏读
不可重复读
同样事务AB并发下操作数据库中同一数据,首先事务A对该数据进行查询,查询之后又进行了其他操作。与此同时,事务B执行了更新操作并且成功commit。那么当事务A再次对数据库查询的时候就会出现与上次读取到的数据不一致的情况
幻读
事务AB并发下操作数据库中同一数据,事务A首先查询了数据库中是否有id=1的数据,没有就插入。那么此时事务A未查询到该数据存在,同时事务B执行了插入操作插入了id=1的数据并且提交。那么事务A再去插入的时候则会报主键冲突的错误,但是当事务A再一次去查的时候发现id=1的数据仍然是不存在( 前提是已经解决了不可重复读的问题,一个事务多次访问同一数据的结果是一致的 ),这种情况就称之为幻读
事务隔离级别
隔离级别
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
Read uncommitted(读未提交) | × | × | × |
Read committed(oracle默认)(读已提交) | √ | × | × |
Repeatable Read(mysql默认)(可重复读) | √ | √ | × |
Serializable(可序化) | √ | √ | √ |
× --> 无法解决 √ --> 可以解决
在sql中查看当前事务隔离级别
select @@transaction_isolation;
设置当前事务隔离级别
-- 设置事务隔离级别 set [session|global] transaction isolation level {Read uncommitted | Read committed | Repeatable Read |Serializable};
session是指尽在当前会话中使用该事务隔离级别,global表示全局有效
四种事务隔离级别当中,Serializable可序化级别最高。要求序列化执行sql指令,事务只能一个接一个的执行,不允许并发执行。性能低下
而Read Uncommitted读未提交性能最好,但是存在脏读问题等
加载全部内容