事务的4大特性:
- 原子性
原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚
- 一致性
指事务必须使数据库从一个一致性状态转换到另一个一致性状态,也就是说一个事务执行之前和执行之后必须处于一致状态
- 隔离性
隔离性是当前多个用户并发访问数据库时,数据库为每一个用户开启事务,其中某一个事务不能被其他的事务所干扰,多个并发事务之间要相互隔离,即要达到这样的效果: 对于任意两个并发 的事务T1和T2,在事务T1看来,T2要么在T1开始之前就已经结束,要么在T1结束之后才执行
- 持久性
是指一个事务一旦提交,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统中遇到故障的情况下也不会对视提交事务的操作
数据库的四种隔离级别
- Serializable(串行化): 可避免脏读,不可重复读,幻读
- repeatable read(可重复读) : 可避免脏读,不可重复读
- read committed(读已提交) : 可避免脏读 的发生
- read uncommitted(读未提交) : 最低的级别,任何情况下都可能出现问题
以上四种隔离级别最高 Serializable,最低的是read uncommitted
隔离级别越高,执行效率就越低
mysql默认隔离级别是: repeatable read(可重复读)
oracle数据库只支持串行化级别和读已提交两种级别,默认的是读已提交
因为有了并发事务,多个事务同时执行,根据数据库的隔离级别,会产生如下问题:
- 脏读: 在一个事务的处理过程中读取另一个未提交的事务中的数据
比如:以银行转账为例:
update t_balance set 余额=余额-1000 where card_id='11111';
update t_balance set 余额=余额+1000 where card_id='22222';
如果发生了这样的情况就脏读
在执行完第一个更新语句的时候,但是还没有执行第二个更新语句,另一个事务中读取t_balance表的数据,余额被减,通知用户余额减过了
还没有执行第二条更新语句就回滚了,此时已经提示过余额减过了
- 不可重复读:
针对数据库中某个数据,一个事务范围内多次查询却返回不同结果,这是由于在查询的间隔,被另外的事务把数据修改了
不可重复读和脏读的区别:
脏读是某一个事务读取了另一个未提交的脏数据
不可重复读则是读取了上一个事务提交的数据
- 幻读: 事务非独立执行时发生的一种现象
如: 事务T1对一个表中的所有的行的某个数据做了从”1”修改数据”2”的操作
此时事务T2又对这个表添加一行数据,而这行中指定的列的数据项是”1”,并且提交给数据库,这个操作事务T1的用户查询此表,就会发现存在一行数据为”1”的数据,T1认为自己的操作并没有让数据”1”变成”2”,此种情况是幻读
幻读和不可重复读都是读取了另一个已经提交了的事务,脏读是读取的另一个未提交的事务数据,不可重复读查询的都是同一个数据项,而幻读针对的是一批数据的整体中的某一个数据项