数据库基础

【什么是事务】

  事务是逻辑上的一组操作,要么全部执行,要么全部放弃。最典型的例子就是银行转账,此消彼长是原则,全部的操作必须是一个事务,中间环节若失败,则回滚至最初状态。

 

【事务的特性】

  事务的特性即:ACID

  • 原子性Atomicity):事务是最小的执行单位,不允许分割。
  • 一致性Consistency):执行事务前后,数据保持一致,多个事务对同一个数据读取的结果是相同的。
  • 隔离性Isolation):并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立。
  • 持久性Durability):一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。

 

【事务在并发下的问题】

   并发场景下,多个事务操作同样的数据。可能带来以下问题:

  • 脏读 (Dirty read):读取了未提交生效的数据。即一个事务update期间(未提交),另一个事务read。
  • 丢失修改 (Lost to modify):修改了前序事务未修改完成的数据。即一个事务update期间(未提交),另一个事务也update。
  • 不可重复读 (Unrepeatable read):两次读取read&read期间,另一个事务做了修改update操作。
  • 幻读 (Phantom read):两次读取read&read期间,另一个事务做了新增insert / 删除delete操作。

 

【解决事务并发问题:事务隔离】

   为了解决以上并发导致的问题,SQL标准定义了四种隔离级别(从低到高):

  • 读取未提交 (Read-Uncommitted) :最低级别,允许读取未提交的数据。
  • 读取已提交 (Read-Committed) :只允许读取已经提交的数据。可以防止脏读
  • 可重复读 (Repeatable-Read) :同一字段的多次读取结果是一致的,除非自身进行了修改。可以防止脏读、不可重复读。MySQL InnoDB 存储引擎的默认支持的隔离级别(使用了Next-Key Lock 锁算法,因此InnoDB的该级别可以达到可串行化的SQL标准级别)。
  • 可串行化 (Serializable) :最高级别,完全遵从ACID隔离级别,所有事务相互独立,互不干扰。可以防止脏读、不可重复读、幻读。
隔离级别防止脏读防止不可重复读防止幻读
READ-UNCOMMITTED × × ×
READ-COMMITTED × ×
REPEATABLE-READ ×
SERIALIZABLE

  可以在SQL中使用以下命令来查看隔离级别:

    SELECT @@transaction_isolation

 

【SQL执行慢的原因】

一、偶尔很慢

  1、数据库正在刷新脏页,占用资源。

    数据库更新时,首先是刷新内存,而不是即刻持久化(IO操作比较耗时);然后把更新的操作写入到redo log中,待数据库空闲时再刷新到磁盘。因为redo log模块容量有限,当它被写满后,数据库就不得不停止其他操作,优先完成数据到磁盘的持久化。这个过程就是刷新脏页。此时客户端提交的SQL操作因为资源问题,执行速度会变慢。

  2、数据库在做并发操作,无法获取到锁。

    多个客户端请求在操作同一张表或同一行数据时,因为数据库的锁机制,后来的操作必须等到前序操作完成释放锁之后,才能进行。因此速度可能也会变慢。使用show processlist命令可以判断当前操作是否在等待锁。

二、一直很慢

  SQL一直很慢多数情况下,就必须考虑SQL的用法是否存在问题了。

  1、未使用索引。没有建立索引,或者因为字段运算、函数操作未能使用索引。

  2、数据库的优化器选错了索引。

 

 

参考文献:(文章仅做交流学习,侵权即删!!)

1、https://github.com/Snailclimb/JavaGuide

2、https://www.cnblogs.com/myseries/p/10719074.html

posted @ 2019-12-11 20:42  不积小流无以成江河  阅读(131)  评论(0编辑  收藏  举报