事务

Posted Im X

tags:

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

事务是什么?

事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消。也就是事务具有原子性,一个事务中的一系列的操作要么全部成功,要么一个都不做。

事务的ACID是指什么?

原子性

原子性说的就是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。

一致性

一致性说的是事务必须使数据库从一个一致性状态变换到另外一个一致性状态。

比如A给B转账100元,A+B的和不变

隔离性

事务和事务是独立的,不能出现并发问题

事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。

持久性

持久性是说的存储数据

持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。

 

如果不考虑事务的隔离性,引发一些安全性问题:

* 脏读      :一个事务读到另一个事务还没有提交的数据. 也就是只做出了更改吗,但是事务还没有提交,读到了日志中的数据,而数据库那个磁盘文件中还没有改变

* 不可重复读 :一个事务读到了另一个事务已经提交的update的数据,导致在当前的事务中多次查询结果不一致.

* 虚读/幻读  :一个事务读到另一个事务已经提交的insert的数据,导致在当前的事务中多次的查询结果不一致.

 

事务的隔离级别

隔离级别是用来保证数据的ACID的,保证高并发环境下数据不受影响的

在数据库操作中,为了有效保证并发读取数据的正确性,提出的事务隔离级别。也就是在高并发的前提下数据不能出现影响。

  ① Serializable (串行化):可避免脏读、不可重复读、幻读的发生。

  ② Repeatable read (可重复读):可避免脏读、不可重复读的发生。   当前事务读不到另一个事务修改后的数据,也就是mysql默认隔离级别,我们需要的。

  对应开发中来说的话,两个用户一个更改数据库,一个读取数据库,两个不同的事务,是读不到另一个用户修改后的数据的。

       两个事务同时开启,一个事务中修改数据,另一个事务是读取不到的,只能读取到未修改前的数据,如果在一个事物修改提交后再开启事务,是可以读取到的。

  ③ Read committed (读已提交):避免了脏读的发生

  ④ Read uncommitted (读未提交):最低级别,任何情况都无法保证。------也就是脏读

 

- 不可重复读:这是描述在同一个事务中两条一模一样的 select 语句的执行结果的比较。如果前后执行的结果一样,则是可重复读;如果前后的结果可以不一样,则是不可重复读。这个特性从字面上也能看出来。

 

     不可重复读的模式下首先不会出现脏读,即读取的都是已提交的数据。在一个事务中,读取操作是不会加排他锁的,当下一条一模一样的 select 语句的执行时,命中的数据集可能已经被其它事务修改了,这时候,还能读到相同的内容吗?

 

     因此,要达到可重复读的效果,数据库需要做更多的事情,比如,对读取的数据行加共享锁,并保持到事务结束,以禁止其它事务修改它。这样会降低数据库的性能。而隔离级别的串行则比可重复读更严格。一般数据库的的隔离级别只设置到读取已提交。这是兼顾了可靠性和性能的结果。

 

     上面还只提到了对命中的数据行加锁,以防止其它事务修改它。但没有提到,如果其它事务增加了符合条件的数据行怎么办?有些数据库对这种情况新定义了两个级别:读取稳定性和游标稳定性。前者不限制新增符合条件的数据行,而后者则阻止新增这样的数据行。

 

- 幻象读:是指两次执行同一条 select 语句会出现不同的结果,第二次读会增加一数据行,并没有说这两次执行是在同一个事务中。一般情况下,幻象读应该正是我们所需要的。但有时候却不是,如果打开的游标,在对游标进行操作时,并不希望新增的记录加到游标命中的数据集中来。隔离级别为 游标稳定性 的,可以阻止幻象读。

 

 

 

大多数的数据库系统的默认事务隔离级别都是:Read committed

  1. READ_COMMITTED (Oracle默认)
  2. REPEATABLE_READ(MySql默认)

 而MySQL的默认事务隔离级别是:Repeatable Read 也就是说mysql是可重复读,用户修改数据和未提交的数据都读不到

而oracle是读已提交:用户更改数据可以读的到。

 

后记:隔离级别的设置只对当前链接有效。对于使用MySQL命令窗口而言,一个窗口就相当于一个链接,当前窗口设置的隔离级别只对当前窗口中的事务有效;对于JDBC操作数据库来说,一个Connection对象相当于一个链接,而对于Connection对象设置的隔离级别只对该Connection对象有效,与其他链接Connection对象无关。

以上是关于事务的主要内容,如果未能解决你的问题,请参考以下文章

数据库事务系列1 事务概述 事务分类

初识事务,事务隔离级别,事务传播行为

事务事务特性事务隔离级别spring事务传播特性

SQL中事务有几种?

Spring 事务控制-存储过程事务

什么叫mysql事务?