数据库事务详解

事务是数据库保证数据一致性的关键机制,具备原子性、一致性、隔离性和持久性。MySQL的InnoDB引擎通过多版本并发控制(MVCC)实现事务,解决了脏读、幻读、不可重复读问题。在MVCC中,快照读和当前读分别对应不同的读取版本,而锁机制如记录锁、间隙锁和Next-Key Locks则用于控制并发。在Java等编程语言中,可以使用相应的API进行事务管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

事务的产生是为了简化我们的编程模型,使我们在开发的过程中不用考虑各种潜在的错误和并发问题,而不是伴随着数据库系统天生就存在的。

事务支持是在引擎层实现的,InnoDB支持事务而MyISAM不支持。

假设数据库不支持事务,看下面的示例:

a账户要转给b账户100元:

update acount set amount =amount -100 where user=a // 1

update acount set amount =amount +100 where user=b // 2

假设程序第一步执行完成了执行到第2步的时候出了问题,那么将导致a账户白白少了100块。此时就能看到事务的重要性了。

数据库事务需要具备四大特性(ACID)

  1. 原子性(Atomicity)

    原子性是指事务不允许部分执行。事务包含的所有操作要么全部成功,要么全部失败并回滚。

  2. 一致性(Consistency)

    如果事务执行期间没有出现系统错误或其他事务错误,并且数据库在事务开始期间是数据一致的,那么在该事务结束时,我们认为数据库仍然保证了一致性。

  3. 隔离性(Isolation)

    如果事务之间不是隔离的,可能会出现以下问题:

    (1) 脏读(dirty read):一个事务在处理过程中读取了另外一个事务未提交的数据。例如事务A中a给b转100块钱,在该事务中首先a的账户减100块,而在此时事务B中查询a的账户发现a少了100块,然后事务A中b账户加钱时发生了意外导致事务A回滚。这个时候事务B拿到的a账户就是脏数据了。

    (2) 不可重复读(none-repeatable read):在一个事务范围内多次查询某个数据却得到不同的结果。例如事务C中b要提现100块,首先查询b账户余额发现有100块满足提现要求,此时事务D中b转账100给a并且提交事务成功,在事务C中再次查询b的账户余额发现已经没有钱了。

    脏读和不可重复读的区别在于脏读是读取到了另一个事务未提交的数据,不可重复读是读取到了其他事务提交的数据。

    (3) 幻读(phantom read):事务E中对一个表中所有数据做了从0修改为1的操作,这时事务F又向这个表插入了一行数据,而这个数据项中值为0并提交事务。此时事务E查询会发现还有一行数据没有修改,这就是幻读。

    不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表。

  4. 持久性(Durability)

    在事务完成以后,该事务对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。

数据库为我们提供了四种隔离级别

事务隔离级别 脏读 不可重复读 幻读
读未提交(read-uncommitted)
读已提交(read-committed)
可重复读(repeatable-read)
串行化(serializable)

MySQL查询当前窗口的事务隔离级别

8以前:select @@tx_isolation;

8:select @@transaction_isolation;

  1. 事务隔离级别为读提交时,写数据只会锁住相应的行。
  2. 事务隔离级别为可重复读时,如果检索条件有索引(包括主键索引)的时候,默认加锁方式是next-key 锁;如果检索条件没有索引,更新数据时会锁住整张表。一个间隙被事务加了锁,其他事务是不能在这个间隙插入记录的,这样可以防止幻读。
  3. 事务隔离级别为串行化时,读写数据都会锁住整张表。
  4. 隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。

MySQL中,默认的隔离级别是REPEATABLE-READ(可重复读),并且解决了幻读问题。简单的来说,mysql的默认隔离级别解决了脏读、幻读、不可重复读问题。

MySQL是如何实现事务的

首先需要了解MVCC(Multi-Version Concurrency Control),它在许多情况下避免了使用锁,同时可以提供更小的开销。根据实现的不同,它可以允许非阻塞式读,在写操作进行时只锁定必要的记录。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值