java笔记 事务以及事务的隔离级别

Posted 多来香菜不要葱

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java笔记 事务以及事务的隔离级别相关的知识,希望对你有一定的参考价值。

事务


 

什么是事务?

事务在数据库中是数据库数据的一种操作序列,事务存在两种状态,要么提交,要么回滚。事务的执行是将数据库从一种状态转换为另外一种状态,从而改变数据库中的数据,数据的改变存在两种方式,新增数据和保持不变,这也就是提交和回滚的另一种表现形式。数据库事务都必须遵循ISO/IEC所制定的ACID原则。所谓的ACID就是:A(atomicity):原子性、C(consistenty):一致性、I(isolation)隔离性、D(durability)持久性;

  • 原子性:既,在数据库操作数据的时候,执行两条或两条以上sql,所有的sql要么全部执行成功,要么全部执行失败,要么全部执行,要么全部不执行,类似于加锁,但是这个加锁是在别的有失败的情况下,那么事务将进行回滚操作将已经执行成功发生改变的数据变回原样;
  • 一致性:既,不管是提交事务,还是回滚事务,数据库都要跟着事务发生改变,发生提交,数据库数据发生改变,发生回滚,数据库状态保持原样。类似于使用银行卡进行转账,用户A给用户B转账,当A的余额扣钱后,B的就要加钱,这里也可以叫合理性,不能A扣钱了,B没有加钱;
  • 隔离性:既,在正在执行还未执行完成的事务所操作的数据,别的事务不能对其改变,也就是在此项事务还没彻底结束之前,不能对正在进行操作的数据进行任何的操作;
  • 持久性:既,数据库在提交某一项事务之后,数据库数据发生改变,之后不管别的事务是否会发生失败都不会影响已经完成事务提交的操作。

事务对于数据库来说是至关重要的,他关系到数据库的数据是否合理,是否完整,是否发生改变后不会因为别的事务发生错误从而影响到已经正常的数据。试想下若是在整个数据库系统中没有了事务的存在,那么你去银行取钱的时候,输入完密码,输入要取的金额,这时候扣款短信已经发到你手机上了,余额已经发生了改变,但是这时候银行突然停电,ATM也跟着断电,那钱肯定吐不出来,相当于,你余额已经发生了改变,但是钱没到你手里,这是非常不合理的,但是若是存在事务,取钱的过程,就是执行sql的过程,在执行完扣款的sql之后,发生意外,这时候事务将进行回滚操作,钱不会吐出来,余额也会变回原来的数值,这就很合理了,这就是事务的好处。

事务的隔离级别


 

并发下事务会发生的问题;
  1. 脏读:所谓脏读就是当事务1开启一个事务,做了数据库的更新操作,此时又开启一个事务2,,读取操作,但是由于某些原因事务1的事务发生了rollback回滚,那么此时事务2查询到到的数据就是事务1更新的数据。此时数据是不准确的,因为事务2在事务1还没执行完成就开启了事务,但是事务1之后又回滚了,导致数据不一致。
  2. 幻读:所谓幻读就是在事务1执行完查询语句的过程中,又开启了一个事务2,此时的事务2是执行的插入语句,但是对于事务1来说,事务2新插入的数据本来是没有的,突然出现,比如:在公司里面,一个部门的总人数是20人,你已经从1到20排好序了,但是此时又新入职几个人,这几个人就是你部门的人,但是是突然出现的,就像是幻觉一样,出现了新员工。
  3. 不可重复读:所谓的不可重复读就是一个事务执行两次查询操作查询到的结果不一致;例如:去银行查询账户余额,那么开启一个事务1查询到的余额为100元,此时事务1还没执行完成,又开启一个线程2,此时线程2执行的是取钱的操作,取走50之后提交事务,现在再切换为事务1,此时事务1查询到的余额就是50元,在同一个事务中,两次查询数据不一致。
事务的隔离级别;
  • DEFAULT:默认的事务隔离级别,每种数据库的默认隔离级别都是不一样的,mysql默认事务的隔离级别为:REPEATABLE-READ,可以使用SELECT @@TX_ISOLATION;来查询数据库默认的隔离级别;
  • READ_UNCOMMITTED:从字面意思直接翻译是,读取未提交的数据,意思为:可以读取未完成事务提交的数据库事务,很显然此隔离级别解决不了脏读的问题;
  • READ_COMMITTED:字面意就是上个级别反过来,读取已经提交的数据,既能读取到已经提交的数据,能解决脏读,但是解决不了幻读和不可重复读;
  • REPEATABLE_READ:重复读取,意思是为某一个事务加锁,在此事务还未提交之前,别的事务都无法为此事务操作的数据进行操作。此级别解决了不可重复读取、脏读,但是解决不了幻读;
  • SERLALIZABLE:串行化,事务的最高隔离级别,简单理解就是为所有的事务全部加锁,在一个事务未执行完成之前,所有的事务都不得干扰正在运行的事务,此事务完完全全的遵循了ACID原则;

不同的事务隔离级别能解决的问题不一致,所消耗的性能也不一样,按需所取,串行化显然消耗性能最高,但是能解决的问题也是最高的,在付出高性能的情况下,给予更稳定的数据安全也是挺好的,当然事务分级别也是为了能提高某些数据库的性能,有的确实不需要用到最高的隔离级别,在高并发环境下,要么要性能不要数据安全,要么保证数据的安全,不要性能,所谓鱼和熊掌不可兼得,取舍很重要,一般情况下使用READ_COMMITTED就完事了。

此资料是在网上参考大佬们写的博客再加上我的一些见解完成的,如有冒犯告诉小弟一声,我来搞定;

 

 

以上是关于java笔记 事务以及事务的隔离级别的主要内容,如果未能解决你的问题,请参考以下文章

事务与隔离级别笔记

数据库事务特性以及隔离级别

oracle学习笔记 事务ACID及隔离级别

8年Java老鸟讲解, 事务的隔离级别,这篇很通透

8年Java老鸟讲解, 事务的隔离级别,这篇很通透

数据库事务的四大特性以及事务的隔离级别-与-Spring事务传播机制&隔离级别