一、概念
数据库中的事物,指的是一连贯的sql指令。要么全部执行完成,一旦中途有一个位置的sql指令执行失败则整个事物内的操作全体回滚,即全部执行失败。
举例来说,我要从A银行账户转400元到B银行账户,要么转账成功A账户减少400元并B账户多400元(手续费之类的就不要考虑了),要么转账失败,A账户被退回400元,B账户金额不变。
真是的案例就是我曾经去建设银行ATM机取款2000元,取款过程中短信通知发过来说我账户取出2000元,但是ATM机却报了异常,让我联系银行。我顿时心就慌了,差点卡忘了拿走,过来1分钟后又收到了银行的短信,账户退回2000元。如果没有事物,那是多么可怕的一件事啊!
二、事物的四大特性
1.原子性:
就同概念说的一样,要么全部执行完成,要么回滚即全部执行失败。
2.一致性:
还是拿转账举例,A、B两个账户总金额是800元,这两个账户之间转账,无论怎么转A+B的金额还是800,多或少。
3.隔离性:
当多个用户并发的向数据库发生访问时,数据库为每一个用户分别开启一个事务,事务与事务的数据是不允许相互干扰的。
4.持久性:
一旦事物提交(commit)完成,数据就永久保存了,不会再受任何情况下影响。
三、隔离性详解
1.如果不隔离的话,存在的问题
a.脏读:
AB两个事务并发开启,A事务读取到了B事务还未提交(commit)的数据。
b.幻读(虚读):
AB两个事物并发开启,B事务insert一条记录,但B事务为提交,A事务读取到了这条记录,但是B事务回滚了,A事务再查询的时候这条记录又消失了。和前一个脏读很像,但是脏读是提前多读出来记录,而幻读是读出来之后又消失了。
c.不可复读:
A事务开启后,select一条记录,因为没有加锁所以此时有可能别的地方正在修改这条记录,A事务再select这条记录时,发现数据与之前的内容不一样了。注意,不可复读不是错误,而是现象。
2.为了解决以上三种问题,有下面这四种隔离级别
a.可序列化(serializable):隔离级别最高,可以避免以上三种问题,但是由於单线程所以性能最低。
b.可重复读(repeatable read):可以避免不可复读、脏读,但是不能避免幻读。
c.已提交读(read committed):可以避免脏读,但是不能避免不可复读、幻读。
d.未提交读(read uncommitted):不设置隔离,三种问题都会发生,但是是性能最高。