事务(Transaction)是并发控制的单位,是用户定义的一个操做序列。这些操做要么都作,要么都不作,是一个不可分割的工做单位。经过事务,数据库能将逻辑相关的一组操做绑定在一块儿,以便服务器保持数据的完整性。
在深刻了解今天的主题以前,须要了解事务的有哪些特性? 事务有四大特性,简称ACID。
1. 原子性(Atomicity)java
原子性是指事务是一个不可分割的工做单位,事务中的操做要么所有成功,要么所有失败。好比在同一个事务中的SQL语句,要么所有执行成功,要么所有执行失败。
2. 一致性(Consistency)mysql
一致性是指在事务开始以前和事务结束之后,数据库的完整性约束没有被破坏。
例如:A+B=100,AB和的状态必须始终保持100。若A=80,则B=20,若A=70,则B=30,他们的和在事务结束先后必须是一致的。
3. 隔离性(Isolation)sql
事务的隔离性是多个用户并发访问数据库时,数据库为每个用户开启的事务,不能被其余事务的操做数据所干扰,多个并发事务之间要相互隔离
4. 持久性(Durability)数据库
持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即便数据库发生故障也不该该对其有任何影响
先回忆一下java多线程下的安全性,假设有一变量count初始值为100,此时有线程A和线程B同时对变量count进行操做。线程A进行操做: count = count +1,在线程A赋值以前,CPU的执行权切换到线程B,此时线程B读取到的count仍然为100,线程B进行操做: count = count +2。
那么出现的问题就显而易见了,最后执行操做的线程回覆盖前者。而咱们在java中的一般作法是给代码块加锁或者变量定义为 AtomicInteger类型的原子性变量。回到mysql,该如何实现呢?
假设有一银行帐户count,小明和小强对其同时进行操做。以下图:安全
为了保证小明在存款时小强不能取现,或者小强在取现时小明不能存款,须要作一个互斥操做!即须要加一个排他锁(Exclusive Lock) , 简称X锁。以下图:服务器
脏读就是指当一个事务正在访问数据,而且对数据进行了修改,而这种修改尚未提交到数据库中,这时,另一个事务也访问这个数据,而后使用了这个数据。
![]()
因为只在写数据的时候加锁但并未在读数据的时候加锁,致使小强读取到了回滚以前的数据。解决方案显而易见,和上面同样加一个X锁不就得了吗?可是仅仅读取数据就加X锁,有点影响性能。 因此,这里为此有专门针对于读数据的锁,即共享锁(Share lock),简称S锁。当一个数据加了X锁, 就无法加S锁, 一样加了S锁, 就无法加X锁。
多线程
不可重复读指在一个事务内读取表中的某一行数据,屡次读取结果不一样。
![]()
如图所述,解决脏读的方案很是简单,在同一事务读取数据时只有把数据读取完才释放锁便可!并发
虚读(幻读)是指在一个事务内读取到了别的事务插入的数据,致使先后读取不一致。
一个事务用Where子句来检索一个表的数据,另外一个事务插入一条新的记录而且符合Where条件,这样,第一个事务用同一个where条件来检索数据后,就会多出一条记录!例如:性能目前工资为1000的员工有10人。
1.事务1,读取全部工资为1000的员工。
2.这时事务2向employee表插入了一条员工记录,工资也为1000
3.事务1再次读取全部工资为1000的员工 共读取到了11条记录。
不可重复读的重点是修改 : 一样的条件, 你读取过的数据,再次读取出来发现值不同了幻读的重点在于新增或者删除: 一样的条件, 第 1 次和第 2 次读出来的记录数不同.测试
mysql数据库默认的事务隔离级别是:Repeatable read(可重复读)
mysql数据库设置事务隔离级别:set transaction isolation level 隔离级别名
查看当前数据库的事务隔离级别:
select @@tx_isolation;
结果以下图,能够清晰的发现当前数据库默认的隔离级别为:REPEATABLE-READ
![]()
为了验证上面聊到的数据库由于隔离级别的不一样而形成的不一样后果,开启如下演示!下面以脏读为例:
1.更改当前数据库的事务隔离级别,并开启事务。
set transaction isolation level read uncommitted; start transaction;
2.在当前窗口A查询count的值,结果为100
3.从新开启一个窗口B,开启事务而且更新数据
start transaction; update account set count = count + 20 where id = 1;
4.切回到窗口A查询count的值,结果为120 ,此时读取到了窗口B中还没有提交的事务。
至于其余演示,本文就暂不作赘述,方法都大同小异。
本人以笔记总结为主,简单概述了事务的四大特性及事务的隔离级别。最后将以幻读为切入点,下篇文章讲讲MVCC的的概念