1、Mysql事务的特性
2、隔离级别
3、死锁
4、Mysql中的事务

START TRANSACTION开启一个事务,COMMIT提交事务或者ROLLBACK回滚事务。
事务开启后,要么执行成功,要么回滚,回滚将不对数据库做任何改动。

一、Mysql事务的四个特性

  • 原子性
    一个事务可视为一个工作单元,要么成功,要么回滚
  • 一致性
    sql操作的所有对象,总是从一个状态一致的转换到另一个状态
  • 隔离性
    事务提交前所做的改动,对其他事务不可见
  • 持久性
    事务一旦提交,所做的改动将会永久的保存到数据库
-- 开启事务
START TRANSACTION ;
SELECT * FROM `data_mall_order`  WHERE id = '1';
UPDATE data_mall_order SET openid = '高陈冰可' WHERE id = '1';
-- 报错sql
UPDATE data_mall_order SET total_amount = '超过Int类型范围值' and phone = '123456789' WHERE id = '1';.
-- 事务提交
COMMIT;

二、事务的隔离级别

  • read uncommitted 未提交读 (脏读)
    事务进行中对数据进行的修改,其他事务是可见的。
    描述:性能与其他隔离级别无太大差距,相反会产生很多数据问题
  • read committed 提交读
    事务进行中,对其他事务提交后的操作数据可读取
    描述:事务进行中,多次对同样记录进行查询,可能会得到不同的结果
  • repeatable read 可重复读(mysql默认的隔离级别)
    事务执行中多次读取同样的记录,结果是一致的,即使其他事务对记录进行操作并提交
    描述:无法避免幻读行为,mysql通过并发控制解决了幻读,后面具体解释幻读是什么。
  • serializable 可串行化
    在读取的数据上加锁,其他事务不可操作
    描述:避免了幻读的情况,但是行锁会导致大量的操作,以及锁挣用的问题,耗性能。

幻读: 在事务A读取某范围数据进行中,事务B在这个范围Insert一条记录并提交,事务A再次进行读取范围数据时,会多出一条数据。

那么问题来了,可重复读与提交读还有什么区别,不都是在事务进行中,其他事务执行提交后,进行中的事务对执行结果可见?

简单说,幻读行为是事务在进行中,其他事务对数据进行删除,新增并提交引起的。
而提交读,与可重复读,是针对数据的修改时,所产生的行为差异

三、死锁
死锁是指两个或者多个事务在同一资源上相互占用,并请求锁定对方占用的资源,从而导致的恶性循环现象。
例:

事务1:
START TRANSACTION;
UPDATE TABLE SET COLUMN = XXX WHERE ID = 1;
UPDATE TABLE SET COLUMN = XXX WHERE ID = 2;
COMMIT;
事务2::
START TRANSACTION;
UPDATE TABLE SET COLUMN = XXX WHERE ID = 2;
UPDATE TABLE SET COLUMN = XXX WHERE ID = 1;
COMMIT;

假如恰巧同时执行以上两个sql,都执行完第一个update,需要去执行第二个update的时候,id 1记录 已被第一个事务锁定,id 2 记录已被第二个事务锁定。两个事务此时都会请求锁定对方占用的资源,而此时两个事务都无法释放资源,由此陷入死锁。

四、Mysql中的事务

  • 自动提交 AUTOCOMMIT
    Mysql默认使用自动提交模式,也就是说如果不是显示的开始一个事务,则每个语句都被当做是一个事务执行提交操作。
    mysql>SET AUTOCOMMIT = 1;可对mysql默认引用自动提交模式进行修改,1表示开启,0表示关闭自动提交模式
    mysql>SET SESSION TANSCTION ISOLATION LEVEL READ COMMITED;设置mysql隔离模式,READ COMMITED 提交可读
  • 事务中混合使用储存引擎
    Mysql服务器层不管事务,事务是由下层的储存引擎实现的,所以在同一个事务中,操作的表使用了不同的储存引擎,是不可靠的。
    如果在事务中混合使用的事务引擎,和非事务引擎(例InnoDB和MyISAM引擎)在正常提交的情况不会出现什么问题。但是当语句需要回滚的时候,InnoDB可以正常回滚,但是MyISAM引擎不能回滚,则出现错误数据。
  • 隐式和显式锁定
    事务执行中过程中,InnoDB引擎随时都可以执行锁定,锁只有在commit 或者rollback的时候才会释放。并且所有的锁都是在同一时刻释放,InnoDB会根据隔离级别在需要的时候自行枷锁,这就是隐式锁定。
    显式锁定:
    使用特定的语句进行显式锁定
select ........LOOK IN SHARE MODE

以上知识来自于对高性能Mysql书籍的理解,如有错误,烦请指出。