Mysql数据库
删库跑路易操作,恢复数据如登天。
前人跑路坦荡荡,后人接盘长戚戚。
一、什么是事务
通常业务人员的一个操作实际上是对数据库读写的多步操作的结合。由于数据操作在顺序执行的过程中,任何一步操作都有可能发生异常,异常会导致后续操作无法完成,此时由于业务逻辑并未正确的完成 当程序发生异常时,说明事务被中断。
解决的办法
1、记录失败的位置,待bug修复后进行从此位置继续执行操作。
2、从当前位置进行回滚,将数据库中的操作恢复至未修改前,然后待bug修复后重新进行事务操作。
二、事务(ACID)的四个属性
事务基本的四个属性 原子性(Atomicity ),一致性,隔离性,持久性
原子性(Consistency ):事务的本身像原子一样不可分割,要么同时执行,要么全部失败。
一致性(Isolation ):指事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。保证数据库一致性是指当事务完成时,必须使所有数据都具有一致的状态。在关系型数据库中,所有的规则必须应用到事务的修改上,以便维护所有数据的完整性。
隔离性(Durability ):并发执行的事务,和他们串行执行时一样。如,多人同时向一个用户赚钱,而当前用户的账户金额应该和一个一个转时相同。
持久性:任何事务一旦提交就会持久化到数据库中,任何事务或系统故障都不会导致数据的丢失。
三、对数据一致性的破坏的两种情况
1、事务的并发执行
对于事务的隔离性,DBMS是采用锁机制来实现的。当多个事务同时更新数据库中相同的数据时,只允许持有锁的事务能更新该数据,其他事务必须等待,直到前一个事务释放了锁,其他事务才有机会更新该数据。
2、事务故障或系统故障
日志恢复技术保证了事务的原子性,使一致性状态不会因事务或系统故障被破坏。同时使已提交的对数据库的修改不会因系统崩溃而丢失,保证了事务的持久性。
四、并发事务带来哪些问题?
脏读(读取未提交数据)
脏数据也称为未处理完全的数据,对于一条数据,A正在操作,而此时在操作时,并未进行提交操作,此时B也来对这个数据进行读,读取的是A操作前的数据,于是此时原有的数据就会受到污染,B操作的是A操作前的数,此时就会产生读的错误。
不可重复读(前后多次读取,数据内容不一致)
对于同一条数据,A,先进行了事务的操作且改变了之前的数据,但是未进行提交,此时这个事务又进行了读的操作,于是两次访问的数据一致。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不 可重复读。
幻读(前后多次读取,数据总量不一致)
幻读发生在A事务是发生在对全表修改的操作上,而B事务一般是增加一条记录,于是就会出现新增加的数据未被进行修改,以后进行A 事务的人进行查询操作,会发现并非所有的记录都被修改,好像出现幻觉一样,于是这就是幻读。
事务隔离级别有哪些?
事务隔离级别 脏读 不可重复读 幻读 读未提交(read-uncommitted) 是 是 是 不可重复读(read-committed) 否 是 是 可重复读(repeatable-read) 否 否 是 串行化(serializable) 否 否 否
-
读未提交 (Read uncommitted) -
读提交(Read Committed) -
可重复读(Repeated Read) -
串行化 (Serializable)
五、SpringBoot中对事务的处理
/** 以后补上!!! 1、如何使用事务
六、小实例(银行转账)
1、正常情况下(理想状态下)
public void putHundred1(Integer id1,Integer id2){
userMapper.addMoney(id1);
userMapper.declineMoney(id2);
System.out.println("转账成功!!!!");
}
2、发生异常的情况下(部分情况下)
/**
* 发生断电死机等突然事件
* @param id1
* @param id2
*/
public void putHundred2(Integer id1,Integer id2){
userMapper.addMoney(id1);
//这里用突然的除零异常来进行示例
int i = 1/0;
userMapper.declineMoney(id2);
System.out.println("转账成功!!!!");
}
此情况下的解决办法:
|