并发事务带来的问题

问题

含义

丢失更新( Lost Update )

当两个或多个事务选择同一行 ,最初的事务修改的值,会被后面的事务修改的值覆盖。

脏读( Dirty Reads )

当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。

不可重复读( Non-Repeatable Reads)

一个事务在读取某些数据后的某个时间,再次读取以前读过的数据,却发现和以前读出的数据不一致。

幻读( Phantom Reads )

一个事务按照相同的查询条件重新读取以前查询过的数据,却发现其他事务插入了满定其查询条件的新数据。

事务隔离级别

隔离级别

丢失更新

脏读

不可重复读

幻读

read uncommitted

no

yes

yes

yes

read committed

no

no

yes

yes

repeatable read(default)

no

no

no

yes

serializable

no

no

no

no

锁分类

  1. 按对数据的操作粒度分:
  • 表锁:锁定整个表。
  • 行锁:锁定当前行。
  1. 对数据的操作类型分:
  • 读锁
  • 写锁

MyISAM 锁

显示加表锁

lock table tab_name read;
lock table tab_name write;
[SQL] ... lock in share mode;
[SQL] ... for update;

解锁

unlock tab_name;

查看表锁情况

show open tab_name;

InnoDB 锁

间隙锁危害
当我们用范围条件,而不是使用相等条件检索数据,并请求共享或排他锁时,InnoDB会给符合条件的已有数据进行加锁;对于键值在条件范围内但并不存在的记录,叫做"间隙",InnoDB也会对这个"间隙”加锁,这种锁机制就是所谓的间隙锁( Next-Key锁)。
InnoDB存储引擎由于实现了行级锁定,虽然在锁定机制的实现方面带来了性能损耗可能比表锁会更高一些,但是在整体并发处理能力方面
要远远由于MyISAM的表锁的。当系统并发量较高的时候, InnoDB的整体性能和MyISAM相比就会有比较明显的优势。
但是, InnoDB的行级锁同样也有其脆弱的- -面,当我们使用不当的时候,可能会让InnoDB的整体性能表现不仅不能比MyISAM高,甚至可
能会更差。

优化建议:

  • 尽可能让所有数据检索都能通过索引来完成,避免无索引行锁升级为表锁。
  • 合理设计索引,尽量缩小锁的范围
  • 尽可能减少索弓|条件,及索引范围,避免间隙锁
  • 尽量控制事务大小,减少锁定资源量和时间长度
  • 尽可使用低级别事务隔离(但是需要业务层面满足需求)