show variables like 'autocommit'; 查询是否开启自动提交
@@autocommit为on或1时表示开启自动提交。
set autocommit=0;可以显示的关闭自动提交。
使用MySQL命令 start transaction;可以隐式的关闭自动提交。
commit;命令可以显示的提交事务。
savepoint 保存点名;
rollback to savepoint 保存点名;
release savepoint保存点名;可以删除一个事务保存点。
MySQL的锁:锁的粒度,隐式锁,显式锁,锁类型,锁的钥匙,生命周期。
锁的粒度:服务器及锁(server-level)和存储引擎级锁(storage-engine-level locking)
服务器级锁以服务器为单位,与表的存储引擎无关。
flush tables with read lock; 锁定当前MySQL服务实例,是服务器级读锁
MyISAM 只支持表级锁
InnoDB 支持表级和行级锁。
数据库自动为数据加锁,解锁,这种锁称为隐式锁。隐式锁无需开发人员维护。
读锁(read lock) 也叫共享锁
写锁(write lock) 排他锁或独占锁
锁的钥匙:
多个MySQL客户机并发访问一个数据,如果客户机A对该数据成功加锁,那么A拥有这把锁的钥匙,也只有A能够对该锁进行解锁。
MyISAM引擎 select操作 会添加隐式读说, insert,update,delete会隐式写锁,
即MyISAM引擎都会隐式的添加表级锁。
alter table account engin=MyISAM;
alter table book engin=MyISAM;
lock tables account read;
select * from accout;
select * from book;
unlock tables;
如果一个表需要同时添加读锁和写锁,那么需要为该表起两个别名,以区分读锁和写锁。
read local 与read区别在于 read local是会话级别,后者是全局。
InnDB行级锁:
1: 共享锁 select * from 表 where 条件语句 lock in share mode;
2: 排它锁 select * from 表 where 条件语句 for update;
insert, update , delete会隐式的添加排它锁。
延迟行级锁的生命周期,可以通过添加事务来。
事务中的行级共享锁和排它锁的生命周期从加锁开始,直到事务提交或者回滚,行级锁才会释放。
意向锁是隐式的表级锁,数据库开发人员在向InnoDB表的记录添加行级锁时,InnoDB引擎会先自动向该表添加意向锁,然后在添加行级锁。
意向锁: 意向共享锁(IS) 和 意向排它锁 (IX)
说明:
意向锁虽然是表级锁,但是却表示事务正在查询或更新某一行记录,而不是整个表,因此意向锁之间不会产生冲突。
sql执行完毕后,意向锁会自动解锁,因此意向共享锁生命周期非常短暂,且不受为控制,意向排他锁也是。
InnoDB 表的行级锁是通过对“索引”施加锁的方式实现的,这就意味着,只有通过索引字段检索数据的查询语句或者更新语句,才可能施加行级锁,否则InnoDB将使用表级锁,而使用表级锁势必降低表的并发性能。
show variables like 'innodb_lock_wait_timeout';
show full processlist; 查看当MySQL实例运行的线程信息
kill 线程id;
对于数据库开发人员而言,如果不了解InnoDB行级锁是基于索引实现这一特性,可能会导致大量的锁冲突,从而影响并发性能。
间隙锁(next-key),间隙锁也与索引密切相关。间隙锁会锁住没加锁的相邻的数据
记录锁,仅仅为满足查询范围记录的施加锁
Mysql的事务隔离级别为 repeatable read是 默认使用时间隙锁
隔离级别是 uncommitted或read committed 默认是记录锁
默认下,InnoDB存储引擎一旦出现锁等待超时异常,InnoDB存储引擎既不会提交事务,也不会回滚事务,而这是十分危险的,一旦发生锁等待超时,应用程序应该自定义错误处理程序,由开发人员选择是进一步提交事务还回滚事务。
默认情况下InnoDB存储引擎会自动检测死锁,通过比较参与死锁问题的事务权重,从而选择权重较小的事务进行回滚,并释放锁,以便其他事物获得锁,继续完成事务。每个事务的权重存储在information_schema 数据库INNODB_TRX表的trx_weight字段中。
事务的ACID特性
原子性
一致性
隔离性
持久性
事务的隔离级别:
Read uncommitted 读 未提交数据
Read committed 读已提交数据
Repeatable read 可重复读
Serializable 串行化
脏读:一个事务读取到另一个事务未提交数据。
不可重复读:同一个事务内,两条相同的查询语句的查询结果不一致。
幻读:同一个事务内,两条相同查询语句的查询结果本应该相同。但是,如果另一个事务同时提交了新数据,当本事务更新时,会“惊奇的”发现这些新数据,貌似之前读到的数据是“鬼影”一样的幻觉。
select @@session.tx_isolattion; 查询MySQL服务实例的隔离级别
select @@global.tx_isolation; 查全局
设置隔离级别
set { global | session} transaction isolation level {
read uncommitted | read committed | repeatable read | serializable
}
说明:不可重复读与脏读的区别在于,脏读现象是读取了其他事务未提交的数据;而不可以重复读现象读到的是其他事务已提交的数据。
说明:幻读现象与不可重复读现象的不同之处在于,幻读现象读不到其他事物已经提交的数据,而不可重复读现象读到的是其他事物已经提交的数据。
避免幻读的两个方法:
1:保持事务的隔离级别是repeatable read不变,利用间隙锁的特点,对查询结果集施加共享锁(lock in share mode) 或排它锁 (for update )。这种方法要求数据库开发人了解间隙锁的特点
2:将事务的隔离级别设置为serializable,可以避免幻读现象。