ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

【MySQL篇】事务的认识以及四大特性

【MySQL篇】事务的认识以及四大特性 何为事务-----*事务Transaction是指一组操作的集合这些操作要么全部执行成功要么全部不执行。事务通常用于保证数据库的一致性、完整性和可靠性确保数据的完整性与正确性。有效避免部分执行部分未执行而引起的问题**引入例子 **假设以下场景转账 第一步A用户转账给B用户100元 账户-100 – 从账户A扣款 UPDATE accounts SET balance balance - 100 WHERE account_id ‘A’; 第二步B用户收到A转账100元 账户100 – 向账户B存款 UPDATE accounts SET balance balance 100 WHERE account_id ‘B’; 此时如果第一步完成之后由于受到各种原因例网络波动主机关机MySQL服务器崩溃等等因素导致第二步未操作这可损失大了A凭空丢失100所以这种情况是不允许发生的。 此时由于是俩个操作所有MySQL会将这俩个操作打包成一个操作原子性要么一起完成要么都不完成。 如果中途发生异常此时操作将会进行“回滚”操作所有操作将会被撤销。 **补充MySQL会将每一步操作都会记录在MySQL的日志中所以可以根据日志里面的内容进行还原操作在 MySQL 中事务是由多个 SQL 语句组成的一个操作单元要么所有的操作都成功执行提交commit要么在发生错误时所有操作都不执行回滚rollback。通过事务MySQL 能够提供更强的错误恢复能力并保证数据库在并发访问时的一致性。* *事务的四大特性--------事务有四个核心特性通常被称为 ACID 特性原子性Atomicity一致性Consistency持久性Durability隔离性Isolation### **原子性****在上述操作中将多个操作打包成一个操作时此时代表这个操作具有“原子”的原子就是以前最小的单位不可拆分。*事务中的操作要么全部成功要么全部失败。原子性确保了事务是最小的执行单位无法再分割。即使在事务执行的过程中发生故障数据库也会通过回滚操作使事务的状态恢复到事务开始之前。* *### **一致性**在执行事务开始前后要保证数据是一致的不会出现对不上的情况。一旦触发“回滚”操作也要保证回滚回去的数据跟原来一样事务执行前后数据库的状态必须从一个一致的状态转变到另一个一致的状态。所有事务都必须遵循数据库的完整性约束如主键、外键等确保数据的完整性和准确性。*### 持久性一旦事务提交它对数据库的更改是永久性的即使发生系统崩溃或断电提交的事务所做的更改也会保留下来。*###隔离性****在并发环境下多个客户端同时对服务器发起事务请求一个事务的执行不应受到其他事务的干扰。每个事务应该像是在独占数据库一样执行直到它提交或回滚。在并发环境下可能会产生以下问题脏读不可重复读幻读*####脏读****脏读指的是一个事务读取了另一个事务尚未提交的数据。这可能会导致读取到不一致的数据因为另一个事务可能回滚使得当前事务读取的数据变得无效。例子 假设有一场随堂考试小明学渣抄袭小强学霸的试卷这种行为是不好的只是比喻此时小强写完了试卷给小明抄小明写着写着写完了之后小明就直接提交试卷了。但小强在检查试卷的时候发现检查试卷的时候很多答案填错了那么小强肯定将答案改正了回来,而小明吃了大亏心里想我*****还不如自己写… **核心在于当小强不仅写完试卷并且还检查完毕确保不会修改的情况下小明再去抄写他的答案不然都可能出错解法方法*当事务B查看事务A写操作的数据时候将事务A的数据进行“加锁”此时事务B不能查看A的数据必须等待事务A确定下来才可以查看。 这就相当于降低了 ‘并发能力’也就降低了数据库服务器的处理效率提高了 ‘隔离性’ 也提高了数据的准确性。在并发执行事务过程中相互之间是互相影响的彼此的影响越小隔离性越高反之影响越大隔离性越低。* *####不可重复读在上述基础上我们已经把写操作加上锁这就意味着读操作的事务不能中途查询以免没有查询到最终结果。 例子当我们写博客的时候此时读者必须等我们发布完成之后才能阅读我们的博客。 假设我们写完已经发布了 这是事务A 然后读者去查看博客的内容 这是事务B 当我们发布完 我们还觉得内容需要修改一下 可能存在一点问题 又进行发布了这是事务C **问题出现在事务B此时在读数据的时候此时我们事务C也执行了假设博客页面刷新了事务B发现此时读到的数据跟刚才读到的数据不一样这就是不可重复读问题****解法****在事务B读操作的时候 我们也不能执行事务C必须等事务B执行完之后才能修改数据也就是说在“读数据”的时候也不能“写数据”**所以对事务B读操作也加上“锁”就可以保证事务 B 前后两次读取的数据都是一致的。脏读和不可重复读的区别脏读关注的是一个事务读取另一个事务未提交的数据且这个数据可能最终会被回滚因此它是不可靠的。不可重复读关注的是同一个事务内在多次读取同一数据时数据发生了变化通常是由于其他事务的提交导致读取结果不一致。*####幻读****幻读是指一个事务在查询数据时其他事务可能插入、删除或修改记录导致该事务查询的数据集发生变化即查询结果出现幻象。在一个事务中查询的结果集在不同的查询操作之间可能不一致。例子 刚才约定对读和写操作进行加上锁。 事务A发布第一篇博客 **事务B在查询博客的内容 此时我们并不修改第一篇博客的内容闲着也是闲着于是我们继续写了新的一篇博客第二篇博客。 事务C *在B再一次查询的时候发现了多出来了一篇博客此时就是幻读。****解法****当读者在阅读博客的时候叫我们啥事别做了好好休息简单来说就是一个事务一个事务来在执行事务的时候不要执行任何操作*实现串行化操作此时没有并发了因此效率最低并且也是隔离性最高的数据是最准确的。* *####隔离性的隔离级别隔离级别脏读不可重复读幻读适用场景读未提交Read Uncommitted是是是高并发、无需完全一致性的数据场景读已提交Read Committed否是是适用于实时性要求较高的场景可重复读Repeatable Read否否是适用于大部分应用默认隔离级别串行化Serializable否否否保证最大程度的一致性但性能最低#### 总结脏读、不可重复读和幻读都是由于并发事务互相干扰所导致的问题。为了避免这些问题可以选择合适的事务隔离级别 *读未提交出现脏读不可重复读幻读。 *读已提交防止脏读但可能会出现不可重复读和幻读。 *可重复读防止脏读和不可重复读但可能会出现幻读。 *串行化完全避免所有并发问题但性能最差。
返回列表