什么是事务(Transaction)
是指访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。事务通常由高级数据库操纵语言或编程语言(如SQL,C++或Java)书写的用户程序的执行所引起,事务由事务开始和事务结束之间执行的全体操作组成,不可以分割,是一个整体,要么全部执行,要么都不执行。
事务的基本要素(ACID)
1、原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节。事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有发生一样。也就是说事务是一个不可分割的整体,就像化学中学过的原子,是物质构成的基本单位。
2、一致性(Consistency):事务开始前和结束后,数据库的完整性约束没有被破坏 。比如A向B转账,不可能A扣了钱,B却没收到。
3、隔离性(Isolation):同一时间,只允许一个事务请求同一数据,不同的事务之间彼此没有任何干扰。比如A正在从一张银行卡中取钱,在A取钱的过程结束前,B不能向这张卡转账。
4、持久性(Durability):事务完成后,事务对数据库的所有更新将被保存到数据库,不能回滚。
事务的简单使用
格式
- 开启事务:start transaction
- 系列sql操作…
- 事务回滚:rollback(可选可不选,根据场景使用)
- 提交事务:commit
准备数据,A窗口,B窗口,代表两个线程
事务的四种隔离级别
- 读未提交(READ UNCOMMITTED)
- 读提交(READ COMMITTED)
- 可重复读(REPEATABLE READ)
- 可串行化(SERIALIZABLE)
读未提交(READ UNCOMMITTED):一个事务可以读取到另一个事务未提交的数据。会产生脏读。
读提交(READ COMMITTED):见名知意,一个事务要等另一个事务提交后才可以读取数据。也就是只能读取已经提交事务的数据。会产生不可重复读。
可重复读(REPEATABLE READ):就是在开始读取数据时(数据提交时),不在允许修改操作。可能会产生幻读。
可串行化(SERIALIZABLE):可串行化是事务的最高隔离级别,它会强制对事务进行排序,使之不会发生冲突,从而解决脏读、幻读、不可重复读的问题。但是,该级别可能导致大量的超时现象和锁竞争,实际应用中很少使用。
脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是错误的数据
不可重复读:对数据库中的某个数据,一个事务范围内多次查询却返回不同的值,这是因为在查询间隔,被另一个事务修改并提交了。
幻读:事务A多次读取构成中,事务B对数据进行了新增操作,导致事务A多次读取事务不一致。
不可重复读:
-- 设置事务隔离级别
SET SESSION TRANSACTION ISOLATION LEVEL 隔离级别;
-- 查询事务隔离级别
SELECT @@tx_isolation;
示例脏读
流程:A和B线程开启事务,A线程查看所有 ,B线程执行更新,但是未提交,此时,A线程再次查看所有,数据发生了变化,这时B线程后悔了,rollback,B线程相当于从开始到现在什么也没有操作,那么A看到的就是假数据,这就是脏读。
示例读提交
流程:A和B线程开启事务,A线程查看所有 ,B线程执行更新,但是未提交,此时,A线程再次查看所有,数据没有发生变化,A线程提交,B线程查看数据,数据发生了变化,这就是读提交。
示例可重复读
流程:A线程开启事务,A线程查看所有 ,B线程执行更新,此时,A线程再次查看所有,数据没有发生变化,如果A线程没有设置REPEATABLE READ隔离级别,A线程查看数据,数据就发生了变化,这就是可重复读。
可串行化
SERIALIZABLE作为事务的最高隔离级别引入了锁的机制,强制对事务进行排序;故,很容易导致大量的超时现象和锁竞争。所以,当线程A中开启事务执行查询并执行COMMIT之后;其它线程的事务中的操作(B线程)才能得到执行。
















