mysql开启事务的三种方式
(查看事务是否自动提交)show variables LIKE 'autocommit'
手动提交事务:
BEGIN;
START TRANSACTION;
update teacher set name = 'zhangsan' where id = 1;
insert teacher (name,age) value = ('lisi', 30);
COMMIT;
ROLLBACK;
事务原则:原子性,
一致性(符合预设的规则,例如转账,a - 100,则b+100,不能b+90),
隔离性(事务内部实现过程对外部不可见),
持久性(一旦修改会永久保存)
事务并发带来的问题:脏读,不可重复读,幻读(范围查询)
事务的四种隔离级别:
RU(未提交读)未解决并发问题
RC(已提交读)解决脏读问题
RR (可重复读)解决不可重复读
serializable(串行化) 解决所有问题
锁
锁是用于管理不同事务对共享资源的并发访问
加锁效率 表锁>行锁
InnoDB支持表锁(另类的行锁:所有的行都锁住)和行锁
Mysql InnoDB锁类型
共享锁(行锁)(解决不可重复读):又称读锁,只读不能修改
加锁方式:select * from users where id = 1 LOCK IN SHARE MODE
释放锁 commit/rollback
排他锁(行锁)(解决脏读):又称写锁,不能与其他锁共存,只有获取了排它锁的事务是可以对数据进行读取和修改的(其他事务要读取数据可来自于快照)
加锁方式:delete/update/insert 默认加上了排它锁
或者 select * from ... FOR UPDATE
释放锁 commit/rollback
innode-行锁到底锁了什么?
只有在索引字段上加行级锁,innodb才使用行锁,非索引字段上加行锁,innodb会使用表锁(锁住所有记录)
表锁:lock tables xx read/write
意向共享锁(表锁):
意向排它锁(表锁):
意向锁是innodb数据操作之前自动加的,不需要用户干预
意义:当事务想去进行锁表时,可以先判断意向锁是否存在,存在则可以快速返回该表不能启用表锁
自增锁:针对自增列自增长的一个特殊的表级锁
show variables like 'innodb_auto_lock_mode'
默认取值1,(强制串行)代表连续,事务未提交id永久丢失
行锁的算法
临建锁(解决幻读):查询按照索引进行数据检索,语句type为range也就是范围查找时,并有记录命中,锁住命中索引的记录+区间(左开右闭)(也就是锁住命中索引所在的区间+下一个相邻的区间)
innodb选择临键锁为默认算法:解决幻读问题
间隙锁:当范围查询或者等值查询且没有满足的记录存在,则会将临键锁退化成gap锁,锁住当前未命中的区间
记录锁:唯一性索引(主键、唯一)索引,条件为精准匹配(=),退化成Record锁
唯一索引、精准匹配、等值查询,只锁住当前记录
死锁:多个并发事务、事物之间产生加锁的循环等待
避免死锁:
1、类似的业务逻辑以固定的顺序访问表和行
2、大事务拆小,同一个事务中,尽可能的一次锁定所有需要的资源,为表添加合理的索引
网友评论