数据库事务的基本概念

来源:互联网 发布:底部反转形态 知乎 编辑:程序博客网 时间:2024/05/18 22:43

数据库事务概念

 

 

数据库事务的4个基本规定(ACID

 

数据库对于事务具有严格规定,即必须满足以下4个特性:

·       原子性(Atomic:表示组成一个事务的多个数据库操作是一个不可分割的原子单元,只有所有操作都执行成功,该事务才可以提交;否则已执行的所有操作都必须撤销,数据库回滚到初始状态;

·       一致性(Consistency):事务操作成功后,数据库所处的状态和它的业务规则是一只的,即数据不会遭到破坏;

·       隔离性(Isolation:在并发数据操作时,不同的事务拥有各自的数据空间,他们的操作不会对对方产生干扰;一般来说隔离级别越高,数据的一致性越好,并发性越弱;

·       持久性(Durabiliy:一旦事务提交成功后,事务中的所有数据操作都必须同步到数据库中;即使在提交事务后,数据库马上崩溃,在数据库重启后,也能通过某种机制回复数据;

 

在这些事务特性中,一致性是事务的最终目标

数据库管理系统一般采用重执行日志来保证原子性、一致性和持久性;重执行日志记录了数据库变化的每一个动作;

数据库采用数据库锁机制来保证事务的隔离性,类似于Java的线程锁机制,当多个事务视图对相同的数据进行操作时,只有持有事务锁的事务才能操作数据;

 

 

数据库锁机制

数据库锁机制用于解决数据库并发产生的问题,保证事务的隔离性;

按锁定的对象不同,可以分为以下2种锁:

·       表锁定:对整张表进行锁定;

·       行锁定:对特定行进行锁定;

 

从并发事务锁定的关系上,可以分为以下2种锁:

·       共享锁定:防止其他的独占锁定,允许其他共享锁定;

·       独占锁定:防止其他的共享锁定,也防止其他的独占锁定;

 

由这2类型的锁定组合,不同数据库有不同的锁定实现;

例如 INSERTUPDATEDELETESELECT FOR UPDATE 等语句都会隐式采用独占的行锁定;

 

 

数据并发可能产生的事务问题

 

在数据库数据并发时,可能会产生以下5种类型的并发错误,包括3种数据数据读写问题(脏读、不可重复读、幻读),2种数据更新问题(第一类丢失问题、第二类丢失问题);

1)脏读(dirty read

A 事务读取 B事务尚未提交的更改数据,并在该基础上进行操作,如果刚好B事务回滚,A事务读取到的数据是不被承认的;

以下是一个典型的事务A与事务B对同一个账户account并发操作,导致脏读示例:

时间

转账事务A

取账事务B

T1

 

开始事务

T2

开始事务

 

T3

 

查询账户余额 account = 1000;

T4

 

取出 500,account = 500 ;

T5

查询账户余额 accoun = 500(脏读);

 

T6

 

回滚事务,账户余额恢复 account = 1000;

T7

汇入 100,account = 600;

 

T8

提交事务(此时事务A对于account发生了脏读)

 

2)不可重复读(unrepeatable read

A 事务读取了 B事务已经提交的更改数据,照成 A事务前后读取同一个数据不一致的现象;

时间

转账事务A

取账事务B

T1

 

开始事务

T2

开始事务

 

T3

 

查询账户余额 account = 1000;

T4

查询账户余额 account = 1000

 

T5

 

取出 200,account = 800;

T6

 

提交事务

T7

查询到账户余额 account = 800(与T4读取的数据不一致,此时事务 A 还未提交)

 

3)幻读(phantom read

幻读一般发生在计算统计数据的事务中,A事务读取了 B 事务提交的新增行数据,照成 A 事务前后计算统计不一致的现象;

时间

转账事务A

取账事务B

T1

 

开始事务

T2

开始事务

 

T3

统计总存款为 10000;

 

T4

 

新增一个存款账户,存款为 100

T5

 

提交事务

T6

再次统计总存款为 100100(幻读)

 

4)第一类丢失更新

A 事务回滚时,把已经提交的 B事务的更新数据覆盖了,该现象为第一类丢失更新;

时间

转账事务A

取账事务B

T1

开始事务

 

T2

 

开始事务

T3

查询账户余额 account = 1000

 

T4

 

查询账户余额 account = 1000

T5

 

汇入100,余额 account = 1100

T6

 

提交事务

T7

取出100,余额 account = 900

 

T8

回滚事务

 

T9

余额恢复 account = 1000(丢失更新)

 

5)第二类丢失更新

A 事务覆盖 B事务已经提交的事务,照成 B 事务所做的操作丢失;

时间

转账事务A

取账事务B

T1

 

开始事务

T2

开始事务

 

T3

 

查询账户余额 account = 1000

T4

查询 account = 1000

 

T5

 

取出 100,余额更改 account = 900

T6

 

提交事务

T7

汇入 100,账户余额更改 account = 1100

 

T8

提交事务

 

T9

账户余额最终为 1100(丢失更新)

 



 

数据库隔离级别

尽管数据库已经为用户提供了锁的 DML操作方式,但是直接使用锁管理还是很麻烦,由此数据库为用户提供了自动锁功能;当用户指定会话的事务隔离级别,数据库会自动分析事务中的 SQL语句,然后自动为事务操作的事务资源添加合适的锁,并同时维护这些锁;

 

ANSI/ISO SQL 92 标准定义了以下由低到高的 4个等级的事务隔离级别;

隔离级别

脏读

不可重复读

幻读

第一类丢失更新

第二类丢失更新

READ UNCOMMITED

允许

允许

允许

不允许

允许

READ COMMITED

不允许

允许

允许

不允许

允许

REPEATABLE READ

不允许

不允许

允许

不允许

不允许

SERIALIZABLE

不允许

不允许

不允许

不允许

不允许

 

SQL 92 推荐使用 SERIALIZABLE等级的隔离,以确保数据的读一致性,不过用户可以根据实际需求选择合适和隔离等级;

 

原创粉丝点击