1.首先我们应该明白什么是事务?
事务具有以下几个特性:
1 一个最小的不可再分的工作单元
2通常一个事务对应一个完整的业务【例如银行账户转账业务,该业务就是一个最小工作单元不可再分】
3一个完整的业务需要批量的DML(insert,update,delete)语句联合完成
4事务应和DML语句有关也就是说DML语句才有业务
以上所指的“批量的DML语句”共有多少条与这个业务逻辑有关,业务逻辑不同,所需的DML语句也不同。
2.关于银行账户转账操作,账户转账是一个完整的业务,最小单元不可再分,就是说银行转账是一个事务。
建立如下的银行账户表
t_act账户表
actno balance
-------------------------
act001 50000.00
act002 10000.00
执行转账10000.00操作的语句如下:update t_act set balance=40000.00 where actno=act001;
update t_act set balance=20000.00where actno=act002;
以上的DML语句必须同时成功或者同时失败,最小单元不可再分。
当第一条DML语句执行成功之后,并不能将底层数据库中第一个账户的数据修改,指示将操作记录了一下,这个记录在内存中完成的,当第二条DML语句执行成功之后,和底层数据库文件中的数据完成同步。若第二条DML语句执行失败,则要清除内存中的记录并且不执行第一条语句,这时候就必须借助事务。
3.事务的四个特性
A:原子性:事务是最小的工作单元,不可再分,要么不做要么全做。
C:一致性:事务要求所有的DML语句操作时,同时完成或同时失效
I:隔离型:事务A和事务B之间具有隔离,一个事务的执行不能被其他事务干扰。
D:持久性:事务一旦提交,对数据库的改变是永久的。
4.关于一些用到的术语(不是SQL语句)
-----开启事务 Start Transaction
-----提交事务 commit Transaction
-----回滚事务 rollback Transaction
5 和事务有关的两条重要的SQL语句【TCL】
commit:提交
rollback:回滚
6事务开启的标志:任何一条DML语句的执行,都标志着事务的开启(insert,delete,update)
事务结束的标志(提交或回滚):提交:成功结束:将DML语句的历史记录与底层数据库进行同步
回滚:失败结束:将DML语句的历史记录清除
7在事务进行过程中,在结束之前,DML语句不会改变底层数据库文件的数据。
只有事务成功的结束,才会修改底层数据库的数据,一旦修改就是永久的(持久性);
8在MYSQL数据库中管理系统中,事务的提交与回滚
8.1 在MYSQL数据库管理系统中,默认情况下,事务是自动提交的,也就是说执行一条DML语句,便开启事务并提交了事务。这种自动提交机制可以关闭,以下演示了如何关闭自动提交机制:
8.1.1 start transaction;//手动开启事务
DML 语句。。
。。。。
commit;//手动提交事务
8.1.2 start transaction;
DML语句。。
。。。。
rollback; //手动回滚事务
关闭自动提交的第二种方式: set autocommit=off;或set session autocommit=off;
打开自动提交: set autocommit=on;或者set session autocommit=on;
以上的打开和关闭支队当前会话有效。
9事务的四个特性之一:隔离型(isolation)
9.1 事务A和事务B之间具有一定的隔离性,一个事务的执行不能被其他事务干扰。
9.2隔离性有隔离级别(4个)
------- 读未提交(read uncommitted)
-------读已提交(read committed)
-------可重复读(repeatable read)
-------串行化(serializable)
隔离级别从上到下从低到高。
9.3read uncommitted:事务A未提交的数据,事务B可以读取到,所读到的数据为脏数据或称为脏读(Dirty read),这种级别最低,数据库大多比这个高。
9.4 read committed:事务A提交的数据事务B才能读到,隔离级别高于上面的。
换句话说:对方事务提交后的数据才能被当前事务读取到,避免了读脏数据,这种隔离级别导致不能重复读。
9.5repeatable read:事务A提交之后,事务B读取不到,事务B是可重复性读取数据
对方提交之后的数据自己还是读取不到,可以避免不可重复读,达到可重复读(MySQL最多应用的隔离级别)
9.6serislizable: 事务A在操作数据表中的数据时,事务B只能排队(这种事务的隔离级别一般很少用,用户体验太差)
可以避免“幻象读”,每一次读取都是真正的记录。