事务四大特性(简称ACID)
1、原子性(Atomicity):事务中的全部操作在数据库中是不可分割的,要么全部完成,要么均不执行。
2、一致性(Consistency):几个并行执行的事务,其执行结果必须与按某一顺序串行执行的结果相一致。事务必须是使数据库从一个一致性状态变到另一个一致性状态。多个账户钱的总和不变
3、隔离性(Isolation):事务的执行不受其他事务的干扰,事务执行的中间结果对其他事务必须是透明的。(即事务隔离级别)(转钱时,从其他用户角度看)
4、持久性(Durability):对于任意已提交事务,系统必须保证该事务对数据库的改变不被丢失,即使数据库出现故障。
事务一致性
强一致性:读操作可以立即读到提交的更新操作。
弱一致性:提交的更新操作,不一定立即会被读操作读到,此种情况会存在一个不一致窗口,指的是读操作可以读到最新值的一段时间。
最终一致性:是弱一致性的特例。事务更新一份数据,最终一致性保证在没有其他事务更新同样的值的话,最终所有的事务都会读到之前事务更新的最新值。如果没有错误发生,不一致窗口的大小依赖于:通信延迟,系统负载等。
其他一致性变体还有:
单调一致性:如果一个进程已经读到一个值,那么后续不会读到更早的值。
会话一致性:保证客户端和服务器交互的会话过程中,读操作可以读到更新操作后的最新值。
事务隔离级别
https://www.51cto.com/article/679914.html
1,脏读
脏读是指在一个事务处理过程里读取了另一个未提交的事务中的数据。
当一个事务正在多次修改某个数据都还未提交,这时另一个并发的事务来访问该数据,就会造成两个事务得到的数据不一致。例如:用户A向用户B转账100元
当只执行第一条SQL时,A通知B查看账户,B发现确实钱已到账(此时即发生了脏读),而之后无论第二条SQL是否执行,只要该事务不提交,则所有操作都将回滚,那么当B以后再次查看账户时就会发现钱其实并没有转。
2,不可重复读
不可重复读是指在对于数据库中的某个数据,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询间隔,被另一个事务修改并提交了。不可重复读出现的原因就是事务并发修改记录,要避免这种情况,最简单的方法就是对要修改的记录加锁,这回导致锁竞争加剧,影响性能。另一种方法是通过MVCC可以在无锁的情况下,避免不可重复读。
例如事务T1在读取某一数据,而事务T2立马修改了这个数据并且提交事务给数据库,事务T1再次读取该数据就得到了不同的结果,发送了不可重复读。
不可重复读和脏读的区别是,脏读是某一事务读取了另一个事务未提交的脏数据,而不可重复读则是读取了前一事务提交的数据。
3,虚读(幻读)
在同一个事务中,同一个查询多次返回的结果不一致。事务A新增了一条记录,事务B在事务A提交前后各执行了一次查询操作,发现后一次比前一次多了一条记录。就好像产生幻觉一样,这就是发生了幻读。幻读是由于并发事务增加记录导致的,这个不能像不可重复读通过记录加锁解决,因为对于新增的记录根本无法加锁。需要将事务串行化,才能避免幻读。
幻读和不可重复读都是读取了另一条已经提交的事务(这点就脏读不同),所不同的是不可重复读查询的都是同一个数据项,而幻读针对的是一批数据整体(比如数据的个数)。
MySQL数据库的四种隔离级别(从低到高、为解决并发事务问题):
①Read uncommitted (读未提交):最低级别,任何情况都无法保证。
②Read committed (读已提交):只有在事务提交后,其更新结果才会被其他事务看见。可避免脏读的发生。
③Repeatable read (可重复读):在一个事务中,对于同一份数据的读取结果总是相同的,无论是否有其他事务对这份数据进行操作,以及这个事务是否提交。可避免脏读、不可重复读的发生。
④Serializable (串行化):事务串行化执行,隔离级别最高,牺牲了系统的并发性。可避免脏读、不可重复读、幻读的发生。
在MySQL数据库中,支持上面四种隔离级别,默认的为Repeatable read (可重复读);而在Oracle数据库中,只支持Serializable (串行化)级别和Read committed (读已提交)这两种级别,其中默认的为Read committed级别。
为什么mysql事务能保证失败回滚
进行事务处理的时候,MySQL 在开始事务时会切换到一个延缓操作的状态,这个状态下操作并不都是立即执行的(通常情况下语句是立即执行的)。而在 commit 时,会将延缓执行的操作都执行进去,并将状态回归到及时写入状态。同样的, rollback 时会把延缓写入的操作抛弃掉,此间申请的锁释放掉,并将状态回归到及时写入状态。
执行 rollback 的关键在于释放 申请的锁 和 回归及时写入状态,而并不是放弃未写入的操作(你关心的点在未写入的操作,然而执行与不执行 rollback 都没有操作写进去,所有你感觉执行或不执行都没什么区别)。
或者是显示地使用savepoint,rollback到之前设置的savepoint