MySQL 事务的简单介绍

MySQL 事务

什么是事务?
事务是用来保证一组数据库操作,要么成功,如果某点失败则回滚所有操作。MySQL默认是自动提交的,每个数据操作都会当作一个事务。通过 autocommit 设置

ACID

事务的特性

  • 原子性 atomicity
    一个事务看做一个原子,作为一个完整的最小工作单元,只有两种结果,要么成功,要么失败,成功则提交,失败则回滚事务内所有操作。
  • 一致性 consistency
    数据库的实际数据是一致的,即在事务成功提交前,外部看数据库数据是没有变化的。
  • 隔离性 isolation
    事务在成功提交之前,对其他事务是不可见的。
  • 持久性 durability
    事务提交成功,数据的修改就会记录到数据库中。即使系统崩溃,数据也不会丢失。

在MySQL中,事务是在存储引擎层实现的。常见额InnoDB就是支持事务的

隔离级别

在特性ACID中,可见两个事务之间是相互隔离的,但在并发时隔离可能会造成数据的一些问题。比如对库存表同时有减库存的操作,开始查时都返回还有剩余库存,但最后执行却只有一个能成功提交,与前面查询结果判断不符。所以对隔离的级别做了配置:

  • 未提交读(read uncommitted)
    即事务还没提交,但他已做的修改是能被其他事务看到的。这种很可能读到未提交的数据,即脏读
  • 提交读(read committed)
    即事务提交后,他的修改才会被其他事务看到。大多引擎都默认这种级别
  • 可重复读(repeatable read)
    意为在事务执行的过程中,其他事务即使提交成功了,也看不到新的修改,InnoDB默认这一级别
  • 可串行化(serializable)
    最高的隔离级别。对同一行数据在一个事务操作时会加锁,其他事务要操作此行数据需要等待当前事务执行完成。此级别确保了数据的一致性,但在面对并发时造成了阻塞
隔离级别脏读不可重复读幻读加锁读
未提交读YYYN
提交读NYYN
可重复读NNYN
可串行化NNNY

通过 set transaction_isolation 命令来调整隔离级别

死锁

指两个或多个事务在争夺同一资源时发生的相互等待的现象,如果没有外力作用,就会一直等待下去,造成死锁。
为了解决死锁,数据库有各种检测和超时机制。InnoDB是可以检测到事务的死锁,回滚一个或多个事务来解决,但有些场景不能检测到,如事务操作中涉及的表用了别的引擎,或者使用了 lock tables 的表锁定语句。这时只能通过超时机制 innodb_lock_wait_timeout,来解决死锁。
为了减少死锁的发生概率,一般在程序设计时:

  • 类似的业务,尽可能按照相同的访问顺序访问
  • 同一事务中,尽可能一次锁定需要的所有资源
  • 同一事务中,不要使用不同的数据引擎的表
  • 控制事务中涉及的资源量
  • 容易产生死锁的业务尝试提升锁的粒度,行锁提升到表锁

事务日志

事务日志即事务操作的日志,它可以提高事务的效率和安全性

  • 修改表数据时,先在内存中修改,再持久化到硬盘上的事务日志,再将内存中的数据慢慢刷到硬盘上,这种方式称为预写式日志。
  • 提高了效率,因为日志是追加式的,也就是顺序IO,相较于随机IO快很多
  • 提高了而安全性,在系统崩溃后,可以通过日志恢复数据
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值