事务和锁

昨天已经写了一次,从图书馆走的时候忘了保存直接关了窗口,心痛。。。

事务是面试时候几乎必问的。虽然心里明白但是无法给出准确回答,再来温习一下。

一。什么是事务

书中的定义是这样的:

   事务就是一组包含一条或多条语句的逻辑单元,每个事务都是一个原子单位,在事务中的语句被作为一个整体, 
要么一起被提交,作用在数据库上,使数据库中数据永久的修改;要么一起被撤销,对数据库不做任何的改变

我理解的是事务是维持数据库中数据的完整性和一致性的必要条件。

每当谈起事务最经典的例子就是银行账户之间的汇款转账操作。这必须是一个原子性的操作。

整个操作在数据库中分为三个过程:

银行从甲方取出钱;

银行把钱存入乙方;

在事务日志中记录该事务

这个交易过程,看做一个事务,如果操作失败,事务就会回滚,所有操作都会撤销,目标账户和源账户上的钱都不会改变;操作成功那么就会被永久提交,目标账户和源账户上的金额都改变了。所以说根据这个例子好好理解一下事务,就是一组操作看做一个整体,要是有一个操作失败了,那就从头来过,不可能说从甲方弄出钱去,还没到乙那失败了,甲方这钱也回不来了,这是不存在的,要是这个整体都成功了,那就成既定事实了,甲方的余额就会减少,乙方的余额就会增多。

事务大概理解了,那到底什么情况才是事务呢?这时候就要看看事务的特性:

1.原子性:原子意味着不可分割,也就是说事务是一个整体,要么全部执行,要么全部不执行,如果都执行成功才可以,即使事务里面一个操作错了,其余的全部成功了,那也不行。操作会被事务撤销。

2.一致性:一致性就是事务执行前后数据库都必须处于一致性状态,只有事务完成后才能被所有使用者看见。例如从甲方取款但是还没有放到乙账户时数据库是不一致的,也是不完整的,其他使用者例如丙并不知道A中修改后的数据,只有存到乙方账户中,交易完成并提交事务,这时才算事务一致,其他用户才能看到修改后的数据。

3.分离性:并发事务之间不能相互的干扰,也就是说,一个事务操作的数据不会被其他事务看到和操作。想一下,甲给乙转钱的同时乙也给甲转,如果事务不分离那不乱套了,想想都乱

4.持久性:一旦成功,数据库中的数据会永久改变。

事务怎么控制呢?

set  transaction:设置事务的属性

commit 提交事务

savepoint:设置保存点

rollback:回滚事务

rollback to savepoint :回滚至保存点

二。事务的类型

事务分为两种类型

1.显示方式

新事务开始
sql statement
...
commit|rollback;

oracle中的事务不需要设置开始标志,通常遇到  1.登录数据库后,第一次执行DML语句;当事务结束后,第一次执行DML语句。 事务会开启

2.隐式方式

没有明确的开始和结束标志,由数据库自动开启,当一个程序正常结束或使用DDL语言时会自动提交,而操作失败时也会自动回滚。如果autocommit 为打开 状态,则每一次执行DML语句都会自动提交。

事务在 1.使用commit提交,使用rollback回滚 2.执行DDL语句,是误会自动提交 3.正常退出SQL*PLUS 时自动提交事务,非正常退出会rollback回滚事务 。 时会结束。

三。事务的保存点

保存点可以根据自己的需要去设置,比如一个事务前十条语句确定没错,就可以在第十条操作结束后设置保存点,这样即使后面的语句错了,回滚到这个保存点就可以。

需要注意的几点是:1.事务只回滚保存点之后的操作 2.回滚到保存点时,它以后的保存点将被删除,但保存点会被保留 3.保存点之后的锁将被释放,但之前的会被保留

如果在事务中使用保存点呢?

 

四。 锁

锁学过java并不陌生,数据库中锁和java中是不是一样呢?来看看锁在数据库中的作用

锁出现在数据共享的的环境中,它是一种机制,在访问相同资源时,可以防止事务之间的破坏性交互。来考虑一下事务的特性,事物的分离性要求当前事务不能影响其他的事务,所以当多个会话访问相同的资源时,数据库系统会利用锁确保它们像队列一样一次进行

来看看锁的分类

1.排他锁(X锁) 也可以叫做写锁,这种模式的锁防止资源的共享,用作数据的修改,假如有事务T给数据A加上该锁,那么其他的事务将不能对A加任何的锁,所以此时只允许T对改数据进行读取和修改,知道事务完成将该类型的锁释放

2.共享锁(S锁)也可以叫读锁,该模式锁下的数据只能被读取,不能被修改,如果有事务T给数据A加上共享锁之后,那么其他事物不能对其加排他锁,只能加共享锁,加了该所得数据可以被并发的读取。

再来看看锁的类型

oracle为了使数据库实现高度的并发访问,它使用了不同类型的锁来管理并发会发对数据对象的操作。

按作用对象不同分为

 1.DML锁:数据锁,用于保护数据

2.DDL锁:可以保护模式中对象的结构

3.内部闩锁:保护数据库的内部结构,完全自动调用。

其中DML锁主要保证了并发访问时数据的完整性,如果再细分,它又可以分为

1)行级锁(TX)也可以称为事务锁。当修改表中某行数据时,需要对将要修改的记录加行级锁,防止两个事务同时修改相同记录,事务结束,该锁也会释放,是粒度最小的锁。属于排他锁(X锁)

2)表级锁(TM)主要作用是防止在修改表的数据时,表的结构发生变化。例如,会话S在修改表A的数据时它会得到表A的TM锁,而此时将不允许其他会话对该表进行变更或删除操作。

来验证一下

首先第一个会话对pro进行修改,获取TM锁,这时候另一个会话想删除pro就会报错

表级锁包含如下几种模式

 

oracle中除了执行DML时自动加锁以外,还可以自己添加,语法是

lock table table in
   [row share]
   [row exclusive]
   [share]
   [share row exclusive]
   [exclusive]
 mode [nowalt]

如果要释放,则需要rollback命令

 

DDL锁又叫做数据字典锁,主要作用是保护模式中对象的结构。当执行DDL操作时,首先oracle会自动隐式提交一次事务,然后自动给处理对象加上所,当DDL结束时,oracle会隐式地提交书屋并释放DDL锁。与DML不同的是,用户不能显式地要求使用DDL锁。

分为三种

1。exclusive ddl lock  排他DDL锁定

2. shared ddl lock 共享DDL锁定

3.breakable parsed lock   

 

锁等待与死锁

锁等待是因为占用的资源不能及时释放,而造成的,上面的例子中,一个花花修改表pro的记录,如果不提交,那么另一个会话就一直没法对pro进行操作

死锁与锁等待不同,它是锁等待的一个特例,通常发生在两个或多个会话之间。假如一个会话想要修改两个资源对象,可以是表也可以是字段,修改这两个资源的操作在一个事务当中。当它修改第一个对象时需要对其锁定,然后等待第二个对象,这时如果另外一个会话也需要修改这两个资源对象,并且易筋经获得并锁定了第二个对象,那么就会出现思索,因为当前会话锁定了第一个对象等待第二个对象,而另一个会话锁定了第二个对象等待第一个对象

 

posted @ 2017-11-06 14:09  竹马今安在  阅读(194)  评论(0编辑  收藏  举报