MySQL InnoDB存储引擎 之 事务

1 事务特性

InnoDB的事务完全符合ACID特性:

  1. 原子性:事务包含的所有操作要么全部成功,要么全部失败回滚;成功必须要完全应用到数据库,失败则不能对数据库产生影响;
  2. 一致性:事务执行前和执行后必须处于一致性状态;
  3. 隔离性:当多个用户并发访问数据库时,数据库为每一个用户开启的事务,不被其他事务的操作所干扰,多个并发事务之间要相互隔离;
  4. 持久性:一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便在数据库系统遇到故障的情况下也不会丢失事物的操作。
2 事务实现

2.1 redo

InnoDB存储引擎中,事务日志通过重做(redo)日志文件和InnoDB存储引擎的日志缓冲(InnoDB Log Buffer)来实现。当开始一个事务时,会记录事务的一个LSN(Log Sequence Number,日志序列号);当事务执行时,回望InnoDB存储引擎的日志缓冲里插入事务日志;当事务提交时,必须把InnoDB存储引擎的日志缓冲写入磁盘(默认的实现,即innodb_flush_log_at_trx_commit=1)。也就是在写数据前,需先写日,称为预写日志方式(Write-Ahead Logging,WAL)。

2.2 undo

undo和redo正好相反,对于数据库进行修改时,数据库不会产生redo,而且还会产生一定量的undo,即使执行的事务或语句由于某种原因失败了,或者想rollback时,可以利用undo信息将数据回滚到修改之前的样子。

3 事务控制语句
  • 关闭自动提交:set autocommit=0
  • 开启事务:start transaction 或 begin
  • 提交: commit 或 commit work (两者区别取决于completion_type的值)
  • 回滚: rollback 或 rollback work (两者区别去接于)
  • 保存点: savepoint xxx
  • 删除保存点: release savepoint xxx
  • 回滚到标记点: rollback to [savepoint] xxx (该语句并没真正结束一个事务,需commit或rollback)
  • 设置隔离级别:set session transaction isolation level xxxx
  • 查看隔离级别: select @@tx_isolation
4 事务隔离级别
  • Read uncommitted(读未提交):最低级别,任何情况都会发生。
  • Read Committed(读已提交):可避免脏读的发生。
  • Repeatable read(可重复读):可避免脏读、不可重复读的发生。
  • Serializable(串行化):避免脏读、不可重复读,幻读的发生。

事务级别带来的一些问题

脏读:(针对未提交的数据)一个事务在更新一条记录,未提交前,第二个事务读到了第一个事务更新后的记录,那么第二个事务就读到了脏数据,会产生对第一个未提交数据的依赖。一旦第一个事务回滚,那么第二个事务读到的数据,将是错误的脏数据。

不可重复读:(读取数据本身的对比)一个事务在读取某些数据后的一段时间后,再次读取这个数据,发现其读取出来的数据内容已经发生了改变,就是不可重复读。

幻读:(读取结果集条数的对比)一个事务按相同的查询条件查询之前检索过的数据,确发现检索出来的结果集条数变多或者减少(由其他事务插入、删除的),类似产生幻觉。

PS:在mysql5.7下试验,默认级别为Repeatable read,该级别把上面三个问题都解决了,其中幻读主要采用mvcc多版本并发控制。


最后PS:

应用程序中,最好的做法是吧事务start transaction、commit、rollback操作交给程序端来完成,而不是存储过程内完成,因为程序端可以捕获出错的异常进行相应的处理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值