一、什么是事物
事物:一个最小的不可分割的工作单元。(例:银行转账业务)
原子操作是对一个单一的对象(包括类域、数组元素等永久对象)数据进行修改过程中发生断电、严重异常等失败情况时,保证原始数据的完整性,即恢复到初始数据状态。事务操作是对一系列的永久数据更新的一个逻辑的集合,要么所有的永久数据的修改都正确完成,要么所有的数据都被恢复为它们以前的值。
银行账户表 tb_act
actno balance
1 500
2 100
转账操作
客户1给客户2转账100
update tb_act set balance = 400 where actno = 1;
update tb_act set balance = 200 where actno = 1;
以上的两条语句必须同时成功同时失败。因为如果一条成功一条失败,就会出现业务问题。如果我们把这两条语句封装为一个事物,要么两条语句同时成功提交要么两条语句同时失败并回滚。
二、事物的四大特征
- 原子性:事物是最小单位,不可再分
- 一致性:事物要求所有的语句进行操作时,必须同时成功或失败
- 隔离性:事物A和事物B之间具有隔离性
- 持久性:内存的数据持久到硬盘文件中
三、一个完整的事物的流程
开启:
任何一条DML语句(insert、update、delete)执行,标志事物开启
或用begin来标志事物的开启
结束:
commit (提交):成功的结束,将所有的DML语句的操作与硬盘数据同步(真正的存到硬盘中)
rollback(回滚):失败的结束,将所有的DML语句回滚到进行事物前,也就是相当于没有对数据进行操作。
我们首先要明白一点:在事物进行的过程中,没有结束的时候,DML语句是不会真正的改变底层的数据的,比如:我没有提交事物,也没有回归事物,那么当我执行完DML语句后,数据不会发生改变。
四、MySQL,事物默认自动提交
也就是说,我只执行了一条DML语句,此时开启了事物,并且也提交了事物。
以上的自动提交机制控制语句为:
SET AUTOCOMMIT=1;自动提交开启(默认为开启)
SET AUTOCOMMIT=0;自动提交关闭
五、事物四大特性之——隔离性
事物A和事物B有隔离性
隔离性级别有四个:
1.读未提交:read uncommitted
2.读已提交:read committed
3.可重复读:repeatable read
4.串行化:serializable
1.读未提交 read uncommitted
有事物A和事物B,A为提交的数据,B可以读取到
这里读到的数据叫"脏数据"
理论存在,但一般数据库的隔离级别都高于该级别
2.读已提交 read committed
有事物A和事物B,A已提交的数据,B才可以读取到
可以避免脏数据,这种隔离级别导致不可重复读取
Oracle的默认隔离级别
3.可重复读:repeatable read
有事物A和事物B,A提交的数据,B读取不到
事物B是可重复读取数据
虽然可以达到可重复读,但会导致幻象读
(幻象读:一个事务先后读取一个范围的记录,但两次读取的纪录数不同,称之为幻象读(两次执行同一条 select 语句会出现不同的结果,第二次读会增加一数据行,并没有说这两次执行是在同一个事务中)。)
幻象读使用最高级别串行化来解决
4.串行化:serializable
有事物A和事物B,事物A在操作数据库时,事物B只能等待
这种隔离级别很少用,吞吐量低,用户体验差
可以避免幻象读
六、隔离级别与一致性关系
七、设置事物隔离级别
方式一
可以在my.ini文件中使用transaction-isolation选项来设置服务器的缺省事务隔离级别。
该选项值可以是:
– READ-UNCOMMITTED
– READ-COMMITTED
– REPEATABLE-READ
– SERIALIZABLE
• 例如:
[mysqld]
transaction-isolation = READ-COMMITTED
- 方式二
- 通过命令动态设置隔离级别
-
-
隔离级别也可以在运行的服务器中动态设置,使用SET TRANSACTION ISOLATION LEVEL语句。
• 其语法模式为:SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL
其中的可以是:
– READ UNCOMMITTED
– READ COMMITTED
– REPEATABLE READ
– SERIALIZABLE
• 例如: SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
八、隔离级别作用范围
• 事务隔离级别的作用范围分为两种:
– 全局级:对所有的会话有效
– 会话级:只对当前的会话有效
• 例如,设置会话级隔离级别为READ COMMITTED :
mysql> SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
或:
mysql> SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
• 设置全局级隔离级别为READ COMMITTED :
mysql> SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED; -
查看隔离级别
• 事务隔离级别的作用范围分为两种:
– 全局级:对所有的会话有效
– 会话级:只对当前的会话有效
• 例如,设置会话级隔离级别为READ COMMITTED :
mysql> SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
或:
mysql> SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
• 设置全局级隔离级别为READ COMMITTED :
mysql> SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;