• 数据库事务


    1、事务是什么      

      【事务是并发控制的基本单位,保证事务ACID的特性是事务处理的重要任务,而并发操作有可能会破坏其ACID特性。 所以事务是针对并发而言的,即对数据在并发操作时保驾护航。

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

    2、事务的四大特性

      数据库事务 transanction 正确执行的四个基本要素。ACID,原子性(Atomicity)、一致性(Correspondence)、隔离性(Isolation)、持久性(Durability)。

      (1)原子性:整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
      (2)一致性:在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。
      (3)隔离性:隔离状态执行事务,使它们好像是系统在给定时间内执行的唯一操作。如果有两个事务,运行在相同的时间内,执行相同的功能,事务的隔离性将确保每一事务在系统中认为只有该事务在使用系统。这种属性有时称为串行化,为了防止事务操作间的混淆, 必须串行化或序列化请求,使得在同一时间仅有一个请求用于同一数据。
      (4)持久性:在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。
    简单理解: 

      原子性:在我理解看来是,事务中各项操作,要么全部成功要么全部失败。很有江湖义气一说,同生共死。

      一致性:我理解的是更侧重结果,事务结束后系统状态是一致的。

      隔离性:并发执行的事务彼此无法看到对方的中间状态。

      持久性:当事务完成后,它对于数据的改变是永久性的,即使出现致命的系统故障也将一直保持。

    在实际生产应用中 针对 事务的隔离性 又划分出了几种隔离级别

      

    并发事务处理带来的问题

    • 更新丢失

      当两个或多个事务选择同一行,然后基于最初选定的值更新该行时,由于每个事务都不知道其他事务的存在,就会发生丢失更新问题–最后的更新覆盖了由其他事务所做的更新

    • 脏读:在一个事务处理过程中读取了另一个未提交事务中的数据。

      

      解读:两个事务 A 和 B,首先 A 事务对 数据 a 执行加 500 的操作 a = 1500,此时 B 事务读取数据 a 的值 1500,后 A 事务 又对数据 a 执行减500 的操作 a = 1000 ,A 事务 commit 。

    • 不可重复读:事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果 不一致。

      

      解读:两个事务 A 和 B,首先 A 事务对 数据 a 进行查询 a = 1000,此时 B 事务对数据 a + 500 操作,并提交事务。后 A 事务 又对 数据 a 进行查询 a = 1500 。

    • 幻读:事务 A 将数据库中所有数据类型从默认的 true 改成 false,但是事务 B 就在这个时候插入了一条新记录,当事务 A改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读。

      小结:不可重复读的和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表。

    MySQL
     
    1.查看当前会话隔离级别
     
    select @@tx_isolation;
     
    2.查看系统当前隔离级别
     
    select @@global.tx_isolation;
     
    3.设置当前会话隔离级别
     
    set session transaction isolatin level repeatable read;
     
    4.设置系统当前隔离级别
     
    set global transaction isolation level repeatable read;
     
     
    Oracle
     
    oracle数据库支持READ COMMITTED 和 SERIALIZABLE这两种事务隔离级别。
     
    1.查看系统默认事务隔离级别,也是当前会话隔离级别
     
    --首先创建一个事务
    declare
         trans_id Varchar2(100);
      begin
         trans_id := dbms_transaction.local_transaction_id( TRUE );
      end; 
     
    --查看事务隔离级别
     
    SELECT s.sid, s.serial#,
     
      CASE BITAND(t.flag, POWER(2, 28))
        WHEN 0 THEN 'READ COMMITTED'
        ELSE 'SERIALIZABLE'
      END AS isolation_level
    FROM v$transaction t
    JOIN v$session s ON t.addr = s.taddr AND s.sid = sys_context('USERENV', 'SID');
     
     
    SQL Server
     
    查看系统当前隔离级别
     
    DBCC USEROPTIONS 
     
    isolation level 这一项的 Value 既是当前的隔离级别设置值
     
    2.设置系统当前隔离级别
     
    SET TRANSACTION ISOLATION LEVEL Read UnCommitted;
     
    其中Read UnCommitted为需要设置的值

      DBMS 数据库管理系统(Database Management System)

    参考:

    1、https://www.jianshu.com/p/03d1bf80f7e8(知识很全面)

    2、https://blog.csdn.net/haochaoguo1988/article/details/82228598

  • 相关阅读:
    java wait方法
    thread join
    AtomicReference 原理
    exchanger java另一种栅栏
    CyclicBarrier 栅栏 原理,应用场景
    信号量Semaphore
    FutureTask 解析
    CountDownLatch
    java 双端队列 Deque
    lockInterruptibly 和lock 原理
  • 原文地址:https://www.cnblogs.com/116970u/p/11447599.html
Copyright © 2020-2023  润新知