一:事务的概念
事务(Transaction)是由N步数据库操作序列组成的逻辑执行单元,这系列操作要么全执行,要么全放弃执行。
二:事务的四大特性
- 原子性(Atomicity):事务是应用中不可再分的最小执行体。
- 一致性(Consistency):事务执行的结果,须使数据从一个一致性状态,变为另一个一致性状态。
- 隔离性(Isolation):各个事务的执行互不干扰,任何事务的内部操作对其他的事务都是隔离的。
- 持久性(Durability):事务一旦提交,对数据所做的任何改变都要记录到永久存储器中。
三:事务管理
1.事务处理
-- 0.开启事务
START TRANSACTION;
-- 1.张三账户 -500
UPDATE account SET balance = balance - 500 WHERE NAME = 'zhangsan';
-- 出错了
-- 2.李四账户 +500
UPDATE account SET balance = balance + 500 WHERE NAME = 'lisi';
-- 发现执行没有问题,提交事务
COMMIT;
-- 发现出问题了,回滚事务
ROLLBACK;
2.事务提交的两种方式
(1)自动提交
MySQL数据库中事务默认提交的方式为自动提交
每执行一条DML(增删改)语句会自动提交一次事务
(2)手动提交
Oracle数据库中事务默认提交的方式为手动提交
需要先开启事务,再提交
修改事务的默认提交方式:
* 查看事务的默认提交方式:SELECT @@autocommit;
// 1 代表自动提交,0 代表手动提交
* 修改事务的默认提交方式:set @@autocommit = 0;
3.事务的隔离级别
概念:多个事务之间是隔离的,相互独立的。但是如果多个事务操作同一批数据,则会引发一些问题,设置不同的隔离级别就可以解决问题
(1)常见的并发异常
- 第一类丢失更新:某一个事务的回滚,导致另外一个事务已更新的数据丢失了。
- 第二类丢失更新:某一个事务的提交, 导致另外一个事务已更新的数据丢失了。
- 脏读:某一个事务, 读取了另外一个事务未提交的数据。
- 不可重复读:某一个事务, 对同一个数据前后读取的结果不一致。
- 幻读:某一个事务, 对同一个表前后查询到的行数不一致。
(2)常见的隔离级别
- Read Uncommitted:读取未提交的数据。
- Read Committed:读取已提交的数据。
- Repeatable Read:可重复读。
- Serializable:串行化
四种事务隔离级别从上到下,级别越高,并发性越差,安全性越来越高。
一般默认隔离级别是读取已提交的数据(Oracle)或可重复读(MySQL)。
查看当前会话中事务的隔离级别
select @@tx_isolation;
设置当前会话中的事务隔离级别
set session transaction isolation level read uncommitted;
设置数据库整体的隔离级别
set global transaction isolation level read uncommitted;
(3)实现机制
在数据库中,进行并发控制的主要方式是使用 封锁机制,即加锁 加锁是一种并行控制技术,是用来调整对共享目标(如数据库中的共享记录)的并行存取的技术。事务通过向封锁管理程序的系统组成部分发出请求而对记录加锁。
所谓加锁就是事务T在对某个数据进行操作之前,先向系统发出请求,封锁其所要使用的数据。加锁后事务T对其要操作的数据具有了一定的控制权,在事务T释放它的锁之前,其他的事务不能操作这些数据。
锁的基本类型有两种:共享锁、排它锁
• 悲观锁(数据库)
- 共享锁(S锁)
又称读锁,若事务T对数据对象A加上S锁,则事务T可以读A但不能修改A,其他事务只能再对A加S锁,而不能加X锁,直到T释放A上的S锁。这保证了其他事务可以读A,但在T释放A上的S锁之前不能对A做任何修改。
事务A对某数据加了共享锁后,其他事务只能对该数据加共享锁,但不能加排他锁。
- 排他锁(X锁)
又称写锁。若事务T对数据对象A加上X锁,事务T可以读A也可以修改A,其他事务不能再对A加任何锁,直到T释放A上的锁。这保证了其他事务在T释放A上的锁之前不能再读取和修改A。
事务A对某数据加了排他锁后,其他事务对该数据既不能加共享锁,也不能加排他锁
• 乐观锁(自定义)
- 版本号、时间戳等
在更新数据前,检查版本号是否发生变化。若变化则取消本次更新,否则就更新数据(版本号+1)。