关于objective-c:操作数据库你不得不知道的-事务-理念

7次阅读

共计 1700 个字符,预计需要花费 5 分钟才能阅读完成。

无论是 iOS 操作 DB、还是 SpringBoot 中 Service 操作 Mybatis,都须要波及到 事务 的概念,如果你在新增一个 DB 增删改 的接口时,没有思考到事务,那么你新增的接口肯定是有问题的。

了解事务

事务是指对系统进行的一组操作,为了保证系统的完整性,事务须要具备 ACID 个性,具体如下:

1. 原子性(Atomic)

一个事务蕴含多个操作,这些操作要么全副执行,要么全都不执行。实现事务的原子性,要反对回滚操作,在某个操作失败后,回滚到事务执行之前的状态。

回滚实际上是一个比拟高层形象的概念,大多数 DB 在实现事务时,是在事务操作的数据快照上进行的(比方,MVCC),并不批改理论的数据,如果有错并不会提交,所以很天然的反对回滚。

而在其余反对简略事务的零碎中,不会在快照上更新,而间接操作理论数据。能够先预演一边所有要执行的操作,如果失败则这些操作不会被执行,通过这种形式很简略的实现了原子性。

2. 一致性(Consistency)

一致性是指事务使得零碎从一个统一的状态转换到另一个统一状态。事务的一致性决定了一个零碎设计和实现的复杂度。事务能够不同水平的一致性:

  • 强一致性:读操作能够立刻读到提交的更新操作。
  • 弱一致性:提交的更新操作,不肯定立刻会被读操作读到,此种状况会存在一个不统一窗口,指的是读操作能够读到最新值的一段时间。
  • 最终一致性:是弱一致性的特例。事务更新一份数据,最终一致性保障在没有其余事务更新同样的值的话,最终所有的事务都会读到之前事务更新的最新值。如果没有谬误产生,不统一窗口的大小依赖于:通信提早,零碎负载等。

其余一致性变体还有:

  • 枯燥一致性:如果一个过程曾经读到一个值,那么后续不会读到更早的值。
  • 会话一致性:保障客户端和服务器交互的会话过程中,读操作能够读到更新操作后的最新值。

3. 隔离性(Isolation)

并发事务之间相互影响的水平,比方一个事务会不会读取到另一个未提交的事务批改的数据。在事务并发操作时,可能呈现的问题有:

  • 脏读:事务 A 批改了一个数据,但未提交,事务 B 读到了事务 A 未提交的更新后果,如果事务 A 提交失败,事务 B 读到的就是脏数据。
  • 不可反复读:在同一个事务中,对于同一份数据读取到的后果不统一。比方,事务 B 在事务 A 提交前读到的后果,和提交后读到的后果可能不同。不可反复读呈现的起因就是事务并发批改记录,要防止这种状况,最简略的办法就是对要批改的记录加锁,这回导致锁竞争加剧,影响性能。另一种办法是通过 MVCC 能够在无锁的状况下,防止不可反复读。
  • 幻读:在同一个事务中,同一个查问屡次返回的后果不统一。事务 A 新增了一条记录,事务 B 在事务 A 提交前后各执行了一次查问操作,发现后一次比前一次多了一条记录。幻读是因为并发事务减少记录导致的,这个不能像不可反复读通过记录加锁解决,因为对于新增的记录根本无法加锁。须要将事务串行化,能力防止幻读。

事务的隔离级别从低到高有:

  • Read Uncommitted:最低的隔离级别,什么都不须要做,一个事务能够读到另一个事务未提交的后果。所有的并发事务问题都会产生。
  • Read Committed:只有在事务提交后,其更新后果才会被其余事务看见。能够解决脏读问题。
  • Repeated Read:在一个事务中,对于同一份数据的读取后果总是雷同的,无论是否有其余事务对这份数据进行操作,以及这个事务是否提交。能够解决脏读、不可反复读。
  • Serialization:事务串行化执行,隔离级别最高,就义了零碎的并发性。能够解决并发事务的所有问题。

通常,在工程实际中,为了性能的思考会对隔离性进行折中。

4. 持久性(Durability)

事务提交后,对系统的影响是永恒的。

示例

举一个近期开发过程中遇到的例子:

 珍藏音乐的业务,有一个 songID(音乐 id)和 localId(珍藏生成的 id)在咱们珍藏一首音乐时:>> 步骤 1:首先须要将 songId 和 localId 的映射关系存到 映射 DB
>> 步骤 2:接着能力将 音乐 存到珍藏业务里。如果步骤 1 失败了,那就肯定不能执行步骤 2,同理,如果步骤 2 失败了,也要同步回滚掉步骤 1 的数据。也就是说:整个珍藏业务肯定是 事务型的。

文章首发:问我社区

正文完
 0