InnoDB
支持事务,支持行锁,支持外键(通常不设置外键,在程序中保持数据的一致性),主流储存引擎,有更高的并发处理性能。MyIsam
不支持事务,支持全文索引,支持表锁,不支持外键,查改速度快,在最新版本的MYSQL中已经废弃。Memory
数据变化频繁,不需要入库,查改极快。进入MySQL数据库通过 show engines;
查看存储引擎,我的版本是MySQL5.7
表级锁
:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。行级锁
:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。页面锁
:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。BEGIN;
UPDATE stu SET sname = '小明' WHERE id=1;
BEGIN;
update stu set sname = '小红' where id=3
COMMIT;
BEGIN;
UPDATE stu SET sname = '小刚' WHERE id=1;
...
COMMIT
提交后,解锁记录行这时B事务继续执行使用非索引字段筛选时,将造成全表锁定即表级锁,应该避免这种情况发生,提升数据库的并发性能。
BEGIN;
UPDATE stu SET sname = '小红' WHERE sname ='小明';
BEGIN;
update stu set sname = '小明' where id=1
-- 阻塞中...
查询没有指定明确范围时也会造成大量记录的锁定
BEGIN;
UPDATE goods SET num=100 WHERE id>1 AND id<3;
BEGIN;
update goods set num =1 where id=2;
-- 阻塞中...
但可以更改ID为1的记录
update goods set num =1 where id=1;
insert into goods (name,num) values('冰箱',200);
非观锁指对数据被外界修改持保守态度,在整个数据处理过程中,将数据处于锁定状态,可以很好地解决并发事务的更新丢失问题。
BEGIN;
SELECT * FROM goods WHERE id=1 FOR UPDATE;
UPDATE goods SET num=num-2 WHERE id=1;
...
BEGIN;
SELECT * FROM goods WHERE id=1 FOR UPDATE;
-- 阻塞中...
在每次去拿数据的时候认为别人不会修改,不对数据上锁,但是在提交更新的时候会判断在此期间数据是否被更改,如果被更改则提交失败。
BEGIN;
SELECT * FROM goods WHERE id = 1;
BEGIN;
SELECT * FROM goods WHERE id = 1;
UPDATE goods SET num=num-10,VERSION =VERSION+1 WHERE VERSION=0;
UPDATE goods SET num=num-10,VERSION =VERSION+1 WHERE VERSION=0;
针对一些不支持事务的处理引擎可以使用锁表的方式控制业务。
#读锁
为表设置读锁后,当前会话和其他会话都不可以修改数据。
LOCK TABLE goods READ;
UPDATE goods SET num=300 WHERE id=1;
SELECT * FROM stu;
update goods set num=200 where id=1;
-- 阻塞
为表设置了写锁后,当前会话可以修改,查询表,其他会话将无法操作。
LOCK TABLE goods WRITE;
INSERT INTO goods (name,num )VALUES('java',300);
select * from goods
UNLOCK TABLES;