Web开发系列(十):事务和锁

事务

事务,有哪四个特性?想必十有八九在面试中问过这个问题:

  • 原子性(Atomicity):事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行
  • 一致性(Consistency):事务应确保数据库的状态从一个一致状态转变为另一个一致状态。一致状态的含义是数据库中的数据应满足完整性约束
  • 隔离性(Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务的执行
  • 持久性(Durability):已被提交的事务对数据库的修改应该永久保存在数据库中

ACID 是数据库事务满足的四个特性,在哪些地方需要用到事务呢?例如在数据库中并发更新一个商品的点赞数,通常的做法是:

  • 取出当前的点赞数
  • +1
  • 把+1之后的值写入数据库

如果这中间存在并发,而恰好CPU调度到另一个进程中执行,数据就有可能紊乱。事务便是因此而生的,事务保证了一系列动作要么全都被 执行,要么全都没有执行。

为了保证并发更新的数据准确性,我们就需要了解到锁这个概念,即,想要修改这个数据,必须要先持有锁,锁的持有者可以更新数据, 其他的只能等待下一次夺取锁。

锁在实现方式上分为乐观锁和悲观锁,乐观锁即认为冲突很少发生,所以每次都会先复制一份先前的数据,记录下时间戳,等到更新数据 的时候,则检查数据是否已经被更改过,如果没有,则更新,否则则回滚,参见MVCC。而悲观锁则相反,采用一种相对保守的策略,悲观锁 认为冲突是极有可能大概率发生的,所以在更新数据之前,一定要先拿到锁才会开始。

参考:


更多文章
  • Nginx 源码阅读(二): 请求处理
  • Nginx 源码阅读(一): 启动流程
  • Go 泛型简明教程
  • KVM 显卡穿透给 Windows
  • 使用 HTTP Router 处理 Telegram Bot 按钮回调
  • 使用反射(reflect)对结构体赋值
  • GIN 是如何绑定参数的
  • 你好 2022(2021 年终总结)
  • 用Go导入大型CSV到PostgreSQL
  • 使用 OpenWRT 搭建软路由
  • 使用软KVM切换器 barrier 共享键鼠
  • SQL 防注入及原理
  • 使用 gomock 测试 Go 代码
  • gevent不是黑魔法(二): gevent 实现
  • gevent不是黑魔法(一): greenlet 实现