数据库事务

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

原文地址:https://www.cnblogs.com/116970u/p/11447599.html