1、InnoDB 支持事务、行级锁。
ACID:
A(atomicity)原子性:要么全部成功,要么全部失败。
C(consistent)一致性:所有相关的数据规则都必须应用于事务的修改,保证数据的完整性。
I(isolation)隔离性:两个事务之间的相互影响。
D(durable)持久性:事务完成后,数据修改永久性。
2、并发事务带来的问题
1、更新丢失:两个事务同时更新一行,由于每个事务不知道其他事务的存在,就会发生更新丢失的问题,最后的更新覆盖了由其他事务所做的更新。
2、脏读:一个事务在对于一条记录做修改,未完成之前,这条记录就处于不一致的状态,此时,另一个事务也来读取同一条记录,读到的为脏数据。
(此时事务未提交,则读取的数据为修改前的数据)。
3、不可重复读:一个事务在读取某些数据后的某个时间,再次读取以前读过的数据,却发现数据发生了改变或被删除。
4、幻读:一个事务按相同的查询条件重读以前检索过的数据,却发现其他事务插入了满足了其查询条件的新数据,称为幻读。
3、事务隔离级别
1、更新丢失:应用的责任
2、脏、不可重复、幻:事务隔离机制
3、实现方式:加锁、多版本并发控制
隔离级别 脏 不可重复 幻
read uncommitted 是 是 是
read committed 否 是 是
repeatable read 否 否 是
serializable 否 否 否
4、查询事务的一些命令
1、查看当前会话的隔离级别:select @@ tx_isolation;
2、查看当前系统的隔离级别:select @@global.tx_isolation;
3、设置当前会话的隔离级别:set session transaction isolation level repeatable read;
4、设置当前系统的隔离级别:set global transaction isolation level repeatable read;
5、命令行,开始事务时:set autocommit=off ; or start transaction ;
5、InnoDB 行锁模式及加锁方式
共享锁:允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。
排他锁:允许获得排他锁的事务更新数据,阻止其他事务取得相同数据集共享读锁和排他写锁。
如果一个事务请求的锁模式与当前锁兼容,InnoDB就将请求的锁授予该事务,反之,如果不兼容,该事务就要等待锁释放。(只有当前是共享锁,请求是共享锁时兼容)。
6、表锁
意向共享锁(IS):事务打算给数据行加行共享锁,事务在给一个数据行加共享锁前必须先取得该表的IS锁。
意向排他锁(XS):事务打算给数据行加行排他锁,事务在给一个数据行加排他锁前必须先取得该表的XS锁。
意向锁是InnoDB自动加的,不需要用户干预,对于update、delete、insert语句,InnoDB会自动给涉及的数据集加排他锁。对于普通的select语句,
InnoDB不会加任何锁。
事务显示加锁:
S:select * from table where ..lock in share mode.
X:select * from table where ..for update.
共享锁主要用在需要数据依存关系时来确认某行记录是否存在,并确认没人对这条记录进行update或delete操作,如果当前事务也需要对该记录进行更新操作,
则很可能造成死锁。对于锁定行记录后需要更新操作的应用,应该使用select..for update方式获得排他锁。
7、InnoDB行锁实现方式
InnoDB行锁是通过给索引项加锁来实现的。这一点mysql与oracle不同,后者是通过数据块中对相应的数据行加锁来实现的。
InnoDB这种行锁意味着,只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁。
是否走索引由执行计划决定,对于一些小表,即使条件中使用了索引字段,有可能走全表扫描,此时InnoDB将使用表锁。
8、mysql常用的命令
show processlist 显示哪些线程在运行
show full processlist
show open tables
show status like '%lock%' 查看服务器状态
show engine innodb status\G; innodb引擎运行信息
show variables like '%timeout%' 查询服务器配置参数
9、mysql查询表死锁 结束死锁的表步骤
是否锁表:show open tables where in_use>0
查进程:show processlist -> kill id
正在锁的事务:select * from information_schema.innodb_locks;
等待锁的事务:select * from information_shcema.innodb_lock_waits;