事务&锁

1.事务的四个特性:
原子性:不可分割的的工作单位,要么都做要么都不做。
一致性:事务将数据库从一种状态变为下一种状态。在事务开始之前和事务结束之后,数据库的完整性约束没有被破坏。
隔离性:每个事务的操作与其他事务相互分离。
持久性:事务一旦提交,结果是永久的,即使宕机数据库也能恢复。
2.事务的实现:
事务的原子性、一致性、持久性都是通过redo log和undo log来完成的。

redo:1.内存中的重做日志缓冲 2.重做日志文件
当事务开始执行的时候,写入缓冲池中的重做日志缓冲,当commit的时候,将缓冲池中的数据进行修改,这些被改过的数据就是脏页。然后将
重做日志缓冲写入重做日志文件,因为重做日志文件打开并没有使用o_direct选项,因此重做日志缓冲先写入文件系统缓冲,之后innodb会调用
一次fsync操作,确保重做日志写入磁盘。
当宕机时,可能会有脏页未写入磁盘,但是我们有了日志文件,就可以保证持久性了。

undo:主要是用于事务回滚。他会记录事务的操作,当需要回滚时,执行了与之前操作相反的操作进行回滚。这里并不是直接把数据库变成事务未执行之前的状态。
因为事务可能是并发的,可能有别的事务在修改数据库别的行,直接变回就错了。这里就保证了一致性。

隔离性:是通过锁实现的。

事务隔离有四种:
1. read uncommited(未提交读):当前会话可以读到其他事务未提交的数据。
problem:很明显会出现很多问题。
2. read commited(提交读):当前会话只能读到其他事务提交后的数据。
Problem:会出现不可重复读。
不可重复读:两个读取结果不一样。事务A读取数据a,事务B将数据a改变,事务A再读发现a和之前不一样了,它读不到以前的a了。
3. read repeated(可重复读):Mysql的隔离机制。也是只能读其他事务提交后的数据,但是第二次读可以读到和第一次读相同的数据,这里的可以读到相同的数据是在update的基础上的,而不是在插入数据的基础上,如果是插入数据会出现幻读。
举个例子:
事务A读取数据a,事务B将数据a改变,事务A再读数据a,发现和之前的a一样。这就是可重复读。
幻读:
事务A读取表中id大于4的数据,它读到了id = 4,id= 5,id = 6的数据,事务B插入了一条数据id是9,事务A再去读,发现多了一个9,跟之前不一样了,他觉得自己出现了幻觉。
所以幻读是:
在同一事务下,连续两个执行同样的SQL语句,导致不同的结果,第二次返回了之前不存在的行。
4. Serializable(串行化):设置这个隔离级别之后,别的会话对表的写操作会挂起,这里就不会出现上述问题了。
Problem:性能会降低。

幻读可以用next_key locking来加锁。
Next_key locking锁定的是一个范围,比如上文的例子,读取id>4的数据,他会将[4, 正无穷)这个区间锁着,其他事务去加id = 9这个操作加不上了,就不会出现幻读了。

4.死锁

死锁的解决方法:
将等待信息画成wait_for graph,采用dfs算法进行死锁检测(有回路出现死锁),选择回滚undo量最小的事务。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值