事务基本特性(ACID,是针对单个事务的一个完美状态)
原子性:
一个事务内的操作,要么都成功,要么都失败。很经典的例子:转账,汇款和收款要成功都成功,要失败都失败。
一致性:
指的是数据的一致性,和原子性其实是一件事情,只不过描述的角度不一样,原子性是从事务的操作的角度,一致性是从数据的角度来描述的,比如转账之前(1000,1000),如果转账100,那么数据状态应该是(900、1100),不应该出现中间状态(900,1000)或者(1000,1100)
隔离性:
事务并发的时候,比如事务1做的动作给员工涨工资2000块,但是此时事务还没有提交,事务2去查询工资发现工资多了2000块,这就是脏读。解决方法就是建立事务之间的隔离机制。
持久性:
事务一旦提交,事务提交,变化即生效。即使数据库服务器宕机,那么恢复之后,数据也应该是事务提交之后的状态,不应该回滚到以前了。
事务并发问题
脏读
1财务发工资
2财务人员今天心情不好,状态不好,误操作发起事务1给员工张三本月涨了1w块钱工资,但是还没有提交事务
3张三发起事务2,查询当月工资,发现多了1W块钱,涨工资了,happ
4财务人员发现不对劲,把操作撤回,把涨工资的事务1给回滚了
在这个过程中,事务2读到了事务1未提交的数据,这就是脏数据,脏读。
幻读(幻读出现在增加insert和删除delete的时候)
1比如事务1查询工资表中工资为1w的员工的个数(10个员工),此时事务1还没有结束
2正在这个时候,事务2,人力部门有两个新员工入职,他们的工资也是1w,人力部门通过事务2向工资表插入了两条记录,并且提交事务了
3这个时候,事务1又去查询工资为1w的员工个数,发现多了两个员工(12个人),见鬼了,这种情况就叫做幻读
不可重复读(出现在修改update的时候)
1员工发起事务1查询工资,工资为1w,事务1尚未关闭
2人力部门发起事务2给你涨了工资,涨工资到1.2W(update你的工资表的字段信息),并且提交了事务了。
3此时,事务1又再次查询自己的工资,发现工资为1.2W,原有的1w这个数据已经读不到了,这就叫做不可重复读
事务隔离级别(解决是事务并发问题的)
极端模式:
读未提交 Read_uncommited,就好比十字路口没有红绿灯一样,效率高,但是风险也高,此时什么事务控制都没有。不要使用这种模式
读已提交
Read_commited,顾名思义,其他事务提交之后,才能读取到这个事务提交的数据,这种模式能解决脏读(因为脏读事务没提交造成的)问题,解决不了幻读和不可重复读(因为这两个问题的产生就是insert delete update的时候提交了事务造成)
可重复读
Repeatable_Read,可重复读解决脏读和不可重复读
极端模式:
串行化:所有的事务一个个来,不争不抢,一个事务处理完了,另外一个事务继续进行,这样不会出现并发问题。比如ATM机
默认:
DEFAULT,默认是数据库的默认,默认模式来源于上面四种模式之一,mysql数据库默认隔离级别可重复读Repeatable_Read,oracle数据库默认级别读已提交Read_commited
事务的传播行为:
在写代码的时候,有可能如下情况:
AService{
xxx(){
....
}
}
BService{
yyy(){
....
}
}
CService{
zzz(){
AService.xxx();
BService.yyy();
}
}