事务隔离级别有4种,但是Spring会提供给用户5种
1)默认(default)
默认隔离级别,每种数据库支持的事务隔离级别不一样,如果Spring配置事务时将isolation设置为这个值的话,那么将使用底层数据库的默认事务隔离级别。顺便说一句,如果使用的MySQL,可以使用"select @@tx_isolation"来查看默认的事务隔离级别
2)读未提交(read_uncommitted)
读未提交,一个事务还未提交时,它做的变更就可以被别的事务看到,即能够读取到没有被提交的数据,所以很明显这个级别的隔离机制无法解决脏读、不可重复读、幻读中的任何一种,因此很少使用
3)读已提交(read_commited)
事务提交以后,它做的变更才能被其它事务看到。但是在这个事务未提交之前,数据库中发生的变更,这个事务也能看见,即能够读到那些已经提交的数据,自然能够防止脏读,但是无法限制不可重复读和幻读
4)可重复读(repeatable_read)
重复读取,事务总是只能看见在启动的那个时刻,数据库的状态。事务未提交之前做的变更,其它事务看不见。事务执行期间,数据库中已经发生的变更,这个事务也看不见。只能看见事务刚启动时刻,数据库的状态,即在数据读出来之后加锁,类似"select * from XXX for update",明确数据读取出来就是为了更新用的,所以要加一把锁,防止别人修改它。REPEATABLE_READ的意思也类似,读取了一条数据,这个事务不结束,别的事务就不可以改这条记录,这样就解决了脏读、不可重复读的问题,但是幻读的问题还是无法解决
5)可串行化(serlalizable)
串行化,最高的事务隔离级别,不管多少事务,挨个运行完一个事务的所有子事务之后才可以执行另外一个事务里面的所有子事务,即事务对某一行的操作会加锁,“写”会加“写锁”,“读”会加“读锁”,在锁释放掉之前,其它的事务都无法对这一行的记录进行操作,必须等之前的事务执行完毕,释放锁,后面的事务又会重新加锁。 这样就解决了脏读、不可重复读和幻读的问题了
番外篇:
1.脏读
所谓的脏读就是指事务A读到了事务B还没有提交到数据,比如银行取钱,事务A开启一个事务,此时切换到事务B,并让事务B开启一个事务并取走100元,此时切换回事务A,事务A读取的肯定是数据库里面的原始数据,因为事务B取走100块钱,但并没有提交,所以数据库里面的账务余额还是原来的数据。这就是脏读。
2.不可重复读
所谓的不可重复读,就是指在一个事务里面读取了两次某个数据,两次读出的数据不一致。以银行取钱为例,事务A开启一个事务,查到银行卡里余额为10000元,此时切换到事务B,并让事务B开启一个事务,事务B取走100元,并提交,数据库里面余额变为了9900元,此时切换回事务A,事务A再次查看账户余额,查出当前余额为9900,这样对事务A而言,在同一个事务内两次读取账户余额数据不一致,值就是不可重复读
3.幻读
所谓的幻读,就是指在一个事务里面的操作中共发现了为被操作的数据。比如员工的信息,事务A开启事务,修改所有员工当天签到状况为false,此时切换到事务B,事务B开启一个事务,事务B插入一条员工数据,此时切换回事务A,事务A提交的时候发现了一条自己没有修改过的数据,这就是幻读,就好像发生了幻觉一样。幻读出现的前提是并发的事务中有事务发生了插入、删除操作。