MySQ事务

x33g5p2x  于2022-05-28 转载在 其他  
字(3.0k)|赞(0)|评价(0)|浏览(302)
事务

事务是访问数据库的一个操作序列,事务的正确执行使得数据库从一种状态转换为另一种状态。事务必须服从ACID原则。原子性(atomicity)、一致性(consistency)、隔离性(isolation)、持久性(durability)。

  • 原子性:不可分割,事务要么全部被执行,要么全部不执行。如果事务的所有子事务全部提交完成,则所有的数据库操作被提交,数据库状态变化;如果有子事务失败,则其他子事务的数据库操作被回滚,即数据库回到事务执行前的状态,不会发生状态变换。
  • 一致性:事务的执行使得数据库从一种正确状态转换为另外一种正确状态。
  • 隔离性:在事务正确提交之前,不允许把事务对该数据的改变提供给任何其他事务。
  • 持久性:事务正确提交之后,其结果永远保存在数据库之中。
事务隔离级别

事务的四种隔离级别

  • READ_UNCOMMITED:读未提交,即能够读取到没有被提交的数据,存在脏读、不可重复读、幻读问题
  • READ_COMMITED:读已提交,即能够读到那些已经提交的数据,存在不可重复读、幻读问题
  • REPEATABLE_READ:可重复读,即在数据读出来之后加锁,即这条事务不结束,其他事务就不可以改这条记录,存在幻读问题
  • SERIALIZABLE:串行化,最高的隔离级别,不管多少事务,挨个运行完一个事务的所有子事务之后才能执行下一个事务,解决所有问题。
数据库悲观锁乐观锁
  • 悲观锁主要是共享锁和排他锁
    ①共享锁又称为读锁,简称S锁,共享锁就是多个事务对于同一个数据可以共享一把锁,都能访问到数据,但是只能读不能修改(lock in share mode)
    ②排他锁又称为写锁,简称X锁,排他锁就是不能与其他锁并存,如一个事务获取了一个数据行的排他锁,其他事务就不能再获取该行的其他锁,包括共享锁和排他锁,但是获取排他锁的事务可以对数据进行读取和修改(for update)
  • 乐观锁一般是以下两种方式
    ①使用版本号,使用数据版本(Version)记录机制实现
    ②使用时间戳,与版本号机制类似
    小结:悲观锁比较是和写入操作比较频繁的场景,乐观锁比较适合读取操作比较频繁的场景
mysql存储引擎
-             MyISAM                 InnoDB
①索引类型:    非聚簇索引               聚簇索引
②支持事务:    否                      是      
③支持表锁:    是                      是
④支持行锁:    否                      是
⑤支持外键:    否                      是
⑥适合操作类型:大量select              大量insert、delete、update
- 表文件
①MyISAM:.frm表结构文件  .MYI表索引文件  .MYD表数据文件
②InnoDB: .frm表结构文件 .ibd表索引和表数据文件
③Memory:数据是保存在内存中,表结构是存在磁盘文件中,所以重启或宕机时,表中数据丢失,
表结构还在。特点:支持HASH索引(等值查询)和B+数索引(范围查找),默认是HASH;
所有字段do欧威固定长度varchar(10) = char(10);使用表级锁。
- 聚簇索引与非局促索引的区别
聚簇索引并不是一种索引类型,而是一种数据存储方式。聚簇索引是将数据存储与索引放到了一块,
找到索引也就找到了数据。非聚簇索引将数据存储与索引分开的结构,索引结构的叶子节点指向了
数据的对应行的物理地址。
mysql索引的分类

mysql索引的五种类型:主键索引、唯一索引、普通索引、全文索引、联合索引。通过添加索引可以提高数据的读取速速,提高项目的并发能力和抗压能力。
①主键索引:主键是一种唯一性索引,但它必须制定为PRIMARY KEY,每个表只能有一个主键
②唯一索引:索引列的所有值都只能出现一次,即必须唯一,值可以为空
③普通索引:基本的索引类型,值可以为空,没有唯一性的限制
④全文索引:全文索引的索引类型为FULLTEXT,全文索引可以在varchar、char、text类型的列上创建
⑤联合索引:多列值组成一个索引,专门用于联合索引
索引按照数据结构来分的话,主要是两种B+树和hash索引

  • 聚簇索引 B+树是左小右大的顺序存储结构,节点只包含id索引列,而叶子节点包含索引列和数据,这种数据和索引在一起存储的索引方式叫聚簇索引,一张表只有主键是聚簇索引。
  • 非聚簇索引 非聚簇索引(二级索引)保存的是主键id值
mysql回表、覆盖索引、最左匹配原则、谓词下推
- 回表:在InnoDB表中,通过普通索引找到主键值,再通过聚簇索引定位到具体的记录,这就是回表。(因为在InnoDB表中,索引使用B+树实现,那么普通索引的叶子节点存的是索引和主键值。)
- 覆盖索引:如果一个索引包含(或覆盖)所有需要查询的字段的值,成为"覆盖索引"。即只需扫描索引而无需回表。
- 最左匹配原则:最左匹配原则是指在联合索引中,如果sql语句中用到了联合索引中的最左边的索引,那么这条sql就可以利用这个联合索引去进行匹配。
- 索引下推:在联合索引的查询场景中,针对特定的过滤条件而进行减少回表次数而坐的优化
当前读和快照读
  • 当前读
    共享锁、排他锁这些操作都是一种当前读,当前读就是读取记录的最新版本,读取时还需要保证其他事务不能修改该记录,会对读取的记录加锁。
  • 快照读
    不加锁的select就是快照读,前提是隔离级别不是串行化级别,串行化的快照读会退化成当前读。之所以出现快照读,基于提高并发性能考虑。MVCC的出现,避免了加锁操作,降低了开销,基于多版本,即快照读可能读到的并不一定是数据的最新版本,可能是某一历史版本。
MVCC

MVCC就是为了实现读-写冲突不加锁,而这个读指的是快照读,而非当前读,当前读是使用悲观锁实现的。MVCC指的是"维持一个数据的多个版本,使得读写操作没有冲突",MVCC模型在mysql中的具体实现是由3个隐式字段,undo日志,Read View等去完成的。

并发场景下的几种问题:
①读-读:不存在任何问题,不需要并发控制
②读-写:有线程安全问题,可能会造成事务隔离性问题,可能遇到脏读,不可重复读,幻读
③写-写:有线程安全问题,可能会存在更新丢失问题

MVCC的好处:
①在并发场景下,读操作不阻塞写操作,写操作不阻塞读操作,提高了数据库并发读写的性能
②解决了脏读、不可重复读、幻读等事务隔离问题,但不能解决更新丢失问题

  • MVCC + 悲观锁
    MVCC解决读写冲突,悲观锁解决写写冲突
  • MVCC + 乐观锁
    MVCC解决读写冲突,乐观锁解决写写冲突

MVCC实现原理

  • 隐式字段
    ①DB_TRX_ID:最近修改事务id
    ②DB_ROLL_PTR:回滚指针,指向这条记录的上一个版本
    ③DB_ROW_ID:隐含的自增主键
    ④实际上还有个删除flag隐藏字段,既记录被更新或删除并不代表真的删除,而是删除flag变了
mysql如何实现串行化

MVCC + next-key locks:next-key locks由record locks(索引加锁/行锁)和gap locks(间隙锁,每次锁住的不光是需要使用的数据,还会锁住这些数据附近的数据)的结合,next-key lock会锁定范围和自身行没比如select…where id < 6,锁定的是小于6的行和等于6的行。
next-ksy lock即在事务中select时使用如下方法加锁,这样在另一个事务对范围内的数据进行修改时就会阻塞:
select * from table where id < 6 lock in share mode; – 共享锁
select * from table where id < 6 for update; – 排他锁

相关文章