事务,其定义是应用程序中一系列不可分割的操作,就是一组可以完成某个业务的代码集合,在关系数据库中,事务可以是一条SQL语句,或者一组SQL语句,亦或整个程序。
其中事务有四个特征,必须同时满足这四个特征才是一个完整的事务。即事务的ACID特性:
原子性(Atomicity):
即事务是数据库的不可分割单元,事务内的操作要么全部执行完成,如果有一个失败,则事务内的操作全部失败。
一致性(consistency):
即事务必须使数据库从一个一致性状态变成另外一个一致性状态,原子性和一致性是密切相关的。
隔离性(isolation):
即事务和事务之间没有影响关系,这个事务的执行不能被其它事务所干扰。并发执行的各个事务不能互相干扰,具有隔离性。
持久性(durability):
如果事务对数据库进行了操作并进行了提交,则数据库对此的改变应该具有持久性,不能因为其它操作或者数据库的损坏而丢失数据。故事务应该具有持久性。
这是事务的四大特性,在并发情况下,事务会产生以下问题:
更新丢失:
两个事务都对同一行数据进行更新,但是第二组事务因为某种原因而中途即退出,所以导致两个事务对数据的修改都失败。
脏读:
一个事务读取了另一个事务没有提交的数据叫做脏读。例如,A事务正在修改数据,但是还没有修改完毕进行提交,这个过程中B事务对这条数据进行了读取操作,B事务产生了脏读。
不可重复读:
一个事务在对数据库进行了再次查询操作,但是却产生了不同结果,或是少了数据行,或是多了未知数据行,此为幻读(一定要明白是数据条数,不是数据本身)。例如,A事务第一次查询此条数据,而B事务对此表进行了插入或者删除操作,而后A事务又再次查询了此表,却产生了与上次不一样的条数记录。故为幻读(进行了INSERT/DELETE操作)。
为了解决以上问题,所以引出了事务的隔离级别:
读未提交:
在该隔离级别,所有事务都可以看到其它事务未提交的内容数据,此隔离级别没有解决任何并发问题,故在应用场景中不常用。
读已提交:
在该隔离级别,一个事务只能读取其它事务已经提交的内容数据,此隔离级别解决了脏读,但没有解决不可重复读和幻读,是ORACLE的默认隔离级别。
可重复读:
在该隔离级别,能保证一个事务之间的多个实例在并发能读取同一数据,此隔离级别解决了脏读和不可重复读,是MYSQL的默认级别。
串行化:
这是最高的隔离级别,在此隔离级别,事务事务之间只能顺序执行,使之没有任何冲突,也就 是从而解决了脏读,不可重复读和幻读,此隔离级别效率较慢,并且有较多的超时现象。
隔离级别越高,越能保证数据的完整性和一致性,但是对并发的效率就越低。一般情况下,采用读已提交或者可重复读,它能够有效避免脏读和不可重复读。