前言
简单整理一下事务。
正文
事务有四大特性:
1.原子性(atomicity)
一个事务必须被视为一个不可分割的最小单元。
2.一致性(consistency)
数据库总是从一个一致性的状态转换到另一个一致性的状态。
很多人对事务的一致性和原子性可能会有偏差。要理解这个东西呢,首先要抛开mysql,或者我们常见的数据库sql server,mongodb。
单纯来理解数据库的事务。
假如有两个事务,事务a和事务b。
假设A和B的两个账号,a账户是500块,b账户是300块。
里面有一个限制就是A账号不能大于600块。
事务a 的逻辑是给A增加100块。然后给B减少100块。
事务b 的逻辑是给B减少100块。然后给A增加100块。
现在事务a,开始执行,做好备份做回滚(500,300),然后给A增加了100块,A现在是600。
现在事务b,开始执行,做好备份做回滚(600,300),然后给B减少了100块,现在B是200。
现在事务a开始执行,给B减少100,B变成了100。也急速说b事务提交的是(600,100)
现在b开始执行,但是报错了,遇到了A不能高于600的限制,现在开始回滚,那么回滚为(600,300)。
那么这个时候就变成了(600,300)了。那么请问事务a和事务b 是否符合原子性?
首先分析事务a,现在能做的,全部执行了。那么是符合原子性的。
然后分析事务b,的确是回滚了,也是符合原子性的。
这有疑问吗?没有吧。
那么事务a和事务b是否符合一致性呢?
a是否符合一致性呢? 数据库总是从一个一致性的状态转换到另一个一致性的状态。
一致性的要求是B账户减少100块,A账户多出100块了。这是一致性的要求。
数据库一开始是:(500,300),然后a提交的时候(600,100),这显然不符合。
b事务其实是符合一致性的,一开始是(500,300),回滚也是(500,300),这没错。
那么是否一致性就一定要原子性呢?
a=a+1;
try{
b=b-1
}catch{
a=a-1;
}
这样其实也是可以一致性的。
那么数据库为什么不这么干呢?比如说 update test set a=a-1;
这个时候回滚的时候还得给你生成一个update test set a=a+1。这是简单的,如果是复杂的,这是要数据库称为人工智能吗?数据库都会傻掉的。
要实现一致性,原子性的成本应该是最低的,但是单单原子性是不能实现一致性的。
3.隔离性
上面我们知道单单原子性是没有实现一致性。那么隔离性就是在原子性的基础上增加一些,一些限制条件那么就可以实现一致性。
比如说,每个事务只能串行执行,这个时候也说符合的,这也是一种隔离级别。但是如果是串行,就不满足并发了,所以就有其他隔离级别了,或者说其他隔离方式。
- 持久性
一旦事务提交,则其所做的修改就会永久保存到数据库中。可能有人说这不是废话吗?事务做的修改不就是要保持带数据文件中,能够持久化吗?
这里面的持久性,表示的更多的是一种方案。持久化是有很多方式的,怎么确保你的持久化方案可行呢?比如说一个事务要修改4条语句分别在四张表,那么怎么确保这四条语句能够全部写入进去呢?会不会写到第二条的时候系统崩溃呢?
如果出现上面的问题,该怎么处理?这就是持久性的重要性了。前三个都是强调语句执行,最后一个强调存储。
结
以上只是个人整理,如有错误,望请指点。
下一节,事务的隔离。