tip:说一下什么是事务,有些同学可能不理解事务是什么意思。
就是我们的一个方法里面有很多的增删改查,如果给这个方法添加事务,那么这个方法的执行就遵循事务的特性。
1.事务的四大特性(原子性(Atomicity)、一致性(Consistency)、隔离型(Isolation)、持久性(Durability))简称ACID。
原子性:举个最简单例子的:i++就不是原子操作,因为第一步i+1,第二步i赋值,并发场景下,两步中间可能插进来别的线程。在mysql中是undo log(回滚日志)实现的
隔离性:指并发的事务相互隔离,不能互相干扰,就是你做你的事情,我做我的事情。通过加锁来实现(悲观锁,乐观锁等)
持久性:数据存到数据库,不会丢失。通过redo log(重写日志)实现。
一致性:插入的数据和数据库存的数据,保证数据的一致。原子性+隔离性+持久性一起实现数据的一致性
2.事务的隔离级别(读未提交(Read Uncommitted),读已提交(Read Committed),可重复读(Repeatable Read),串行化(Serializable))
读未提交:就是说一个事物修改了数据,但是还没有提交,再另一个事务中select语句,会读到这个未提交的数据(称为脏读)
所以说,读未提交是最低级的!
读已提交:读已提交是为了防止脏读的产生,事务读取的数据只能是其他事物都已经提交过得数据,不存在还没有提交的数据被读取。但是这样会产生不可重复读。
不可重复读是指同一个select方法,前后查询的数据不同,数据不能重复读,站在数据层面理解,就叫不可重复读。
产生这个的原因,举个例子:当一个事务A正在提交数据,但是还没有提交,这个时候另一个事务B是读取不到事务A正在准备提交的数据,这时候事务B读取到10调数据,然后事务A完成了提交,事务B又做了一次select查询,数据变成了11条,这就是数据的不可重复读。
可重复读:当然,这个就是为了解决数据不可重复读的问题。可重复读是指在一个事务A中,select查询的结果是事务开始的数据,尽管事务过程中有了很多的其他新数据提交,但是在当前事务中的select语句查询都是事务开始的数据,这样就保证了数据的可重复读,不存在select数据前后不一致的样子。但是,这回产生会有幻读现象。
什么是幻读?其实幻读可以说就是一种视觉现象,事务A的隔离级别是可重复读,在他执行这个事务的过程中,其他事务有修改或添加新的数据,但事务A获取到的数据始终是事务A开始时候的数据,当事务A结束后,发现数据库里突然多了很多数据,仿佛出现了幻觉,所以幻读可以就理解为一种肉眼看到的现象。
串行化:这个很简单了,就是把事务串起来,一个一个执行,这样数据就不会乱了。
注意:虽然事务隔离级别越高,越能保证数据的一致性,但事务隔离级越高,对并发性能影响越大,在这中间必须做一些取舍。
所以现在的大多数数据库的隔离级别是Read committed 读已提交,只要是提交的数据都可以读,但是不保证数据的重复读,比如比如Sql Server , Oracle。
Mysql的默认隔离级别是Repeatable read 可重复读,保证整个事务的过程中,数据的读取都是事务开启时候的一样。