oracle学习(五)——事务与锁

笔者是一个痴迷于挖掘数据中的价值的学习人,希望在平日的工作学习中,挖掘数据的价值,找寻数据的秘密,笔者认为,数据的价值不仅仅只体现在企业中,个人也可以体会到数据的魅力,用技术力量探索行为密码,让大数据助跑每一个人,欢迎直筒们关注我的公众号,大家一起讨论数据中的那些有趣的事情。

我的公众号为:livandata

oracle学习(五)——事务与锁_第1张图片

対事务的处理经常被用在金融领域,以保证多个操作的同步完成,由于事务的种类以及事务与锁的关系比较复杂,此处只对事务的原理做简单的介绍,详细内容可以专项研究事务和锁机制。

1、事务:

 

DML语句主要是指:增删改,没有查询;

 

事务的特性有(ACID):

1)原子性(Atomicity):一个事务里面所有包含的SQL语句是一个执行整体,不可分割,要么都做,要么都不做。
2)一致性(Consistency):事务开始时,数据库中的数据是一致的,事务结束时,数据库的数据也应该是一致的。
3)隔离性(Isolation):是指数据库允许多个并发事务同时对其中的数据进行读写和修改的能力,隔离性可以防止事务的并发执行时,由于他们的操作命令交叉执行而导致的数据不一致状态。
4)持久性 (Durability) : 是指当事务结束后,它对数据库中的影响是永久的,即便系统遇到故障的情况下,数据也不会丢失

常见的数据异常有:

脏读当一个事务修改数据时,另一事务读取了该数据,但是第一个事务由于某种原因取消对数据修改,使数据返回了原状态,这是第二个事务读取的数据与数据库中数据不一致,这就叫脏读。

不可重复读:是指一个事务读取数据库中的数据后,另一个事务则更新了数据,当第一个事务再次读取其中的数据时,就会发现数据已经发生了改变,这就是不可重复读取。不可重复读取所导致的结果就是一个事务前后两次读取的数据不相同。

幻读如果一个事务基于某个条件读取数据后,另一个事务则更新了同一个表中的数据,这时第一个事务再次读取数据时,根据搜索的条件返回了不同的行,这就是幻读。

事务隔离级别:

oracle学习(五)——事务与锁_第2张图片

oracle默认的隔离级别为:read commited;

 

Oracle支持上述四种隔离级别中的两种:read committed 和serializable。除此之外,Oralce中还定义Read only和Read write隔离级别。

Read only:事务中不能有任何修改数据库中数据的操作语句,是Serializable的一个子集。

Read write:它是默认设置,该选项表示在事务中可以有访问语句、修改语句,但不经常使用。

设置隔离级别:

 

  • SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
  • SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
  • SET TRANSACTION READ ONLY;
  • SET TRANSACTION READ WRITE;

注意:这些语句是互斥的,不能同时设置两个或两个以上的选项。

设置单个会话的隔离级别:

  • ALTER SESSION SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
  • ALTER SESSION SET TRANSACTION ISOLATION SERIALIZABLE;

回退事务:

 oracle学习(五)——事务与锁_第3张图片
提交事务:
 
事务的几个重要的操作:
 oracle学习(五)——事务与锁_第4张图片
在java中的事务设置:

 

 

 

 
主要是通过添加ct.setAutoCommit(false);和ct.commit()两个语句,两个语句之间的语句会一起提交。如果提交失败,则在try……catch……中添加et.rollback()方法,以保证语句执行失败时能够回滚;
只读事务:
 oracle学习(五)——事务与锁_第5张图片
机票代售的编写方式为:
管理员在统计时先设置只读事务。
1)系统管理员登录:
 
此时其他用户对数据库的操作都不会显示在这个系统管理员的事务操作中,即在此事务下不会显示其他用户新增的数据。
2)新开一个窗口,登录scott用户,新增一条记录:
 
然后提交此句:
 
3)scott用户操作完成后,再切换到系统管理员用户下,进行统计工作:
Select * from scott.emp;

此时显示的是17行,没有查询到新增的记录。

 

2、锁机制:

数据库是一个多用户使用的共享资源。当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。

在数据库中有两种基本的锁类型:排它锁(Exclusive Locks,即X锁)和共享锁(Share Locks,即S锁)。当数据对象被加上排它锁时,其他的事务不能对它读取和修改;加了共享锁的数据对象可以被其他事务读取,但不能修改。

锁分类:

根据保护对象的不同,Oracle数据库锁可分为:

  • DML lock(data locks,数据锁):用于保护数据的完整性。
  • DDL lock(dictionary locks,字典锁):用于保护数据库对象的结构(例如表、视图、索引的结构定义)。
  • Internal locks 和latches(内部锁与闩):保护内部数据库结构。
  • Distributed locks(分布式锁):用于OPS(并行服务器)中。
  • PCM locks(并行高速缓存管理锁):用于OPS(并行服务器)中。

在Oracle中最主要的锁是DML锁,DML锁的目的在于保证并发情况下的数据完整性。在Oracle数据库中,DML锁主要包括TM锁和TX锁,其中TM锁称为表级锁,TX锁称为事务锁或行级锁。

锁出现在数据共享的场合,用来保证数据的一致性。当多个会话同时修改一个表时,需要对数据进行相应的锁定。

锁有“共享锁”、“排它锁”,“共享排它锁”等多种类型,而且每种类型又有“行级锁” (一次锁住一条记录),“页级锁” (一次锁住一页,即数据库中存储记录的最小可分配单元),“表级锁” (锁住整个表)。

共享锁(S锁)

可通过lock table in share mode命令添加该S锁。在该锁定模式下,不允许任何用户更新表。但是允许其他用户发出select …from for update命令对表添加RS锁。

排他锁(X锁)

可通过lock table in exclusive mode命令添加X锁。在该锁定模式下,其他用户不能对表进行任何的DML和DDL操作,该表上只能进行查询。

行级共享锁(RS锁)

通常是通过select … from for update语句添加的,同时该方法也是我们用来手工锁定某些记录的主要方法。比如,当我们在查询某些记录的过程中,不希望其他用户对查询的记录进行更新操作,则可以发出这样的语句。当数据使用完毕以后,直接发出rollback命令将锁定解除。当表上添加了RS锁定以后,不允许其他事务对相同的表添加排他锁,但是允许其他的事务通过DML语句或lock命令锁定相同表里的其他数据行。

行级排他锁(RX锁)

当进行DML操作时会自动在被更新的表上添加RX锁,或者也可以通过执行lock命令显式的在表上添加RX锁。在该锁定模式下,允许其他的事务通过DML语句修改相同表里的其他数据行,或通过lock命令对相同表添加RX锁定,但是不允许其他事务对相同的表添加排他锁(X锁)。

共享行级排他锁(SRX锁)

通过lock table in share row exclusive mode命令添加SRX锁。该锁定模式比行级排他锁和共享锁的级别都要高,这时不能对相同的表进行DML操作,也不能添加共享锁。

上述几种锁模式中,RS锁是限制最少的锁,X锁是限制最多的锁。它们的兼容关系如下:

oracle学习(五)——事务与锁_第6张图片

基本上所有的锁都可以由Oracle内部自动创建和释放,但是其中的DDL和DML锁是可以通过命令进行管理的,命令语法:

LOCK table_name IN 
    [row share][row exclusive][share][share row exclusive][exclusive] MODE 
[NOWAIT];

下图列出产生锁定模式的SQL语句:

oracle学习(五)——事务与锁_第7张图片

当程序对所做的修改进行提交(Commit)或回滚(Rollback)后,锁住的资源便会得到释放,从而允许其他用户进行操作。如果两个事务,分别锁定一部分数据,而都在等待对方释放锁才能完成事务操作,这种情况下就会发生死锁

锁机制:https://blog.csdn.net/nsj820/article/details/5705718

锁有很多种,常被提及的是乐观锁和悲观锁:

悲观锁:每次都假设数据肯定会存在冲突,数据开始读取时就把数据给锁住;

乐观锁:每次都假设一般情况下不会发生数据冲突,只有数据更新提交的时候,菜户对数据是否冲突进行检测,如果发生冲突,则返回错误信息,让用户处理。

你可能感兴趣的:(数据库)