昨天已经写了一次,从图书馆走的时候忘了保存直接关了窗口,心痛。。。
事务是面试时候几乎必问的。虽然心里明白但是无法给出准确回答,再来温习一下。
一。什么是事务
书中的定义是这样的:
事务就是一组包含一条或多条语句的逻辑单元,每个事务都是一个原子单位,在事务中的语句被作为一个整体,
要么一起被提交,作用在数据库上,使数据库中数据永久的修改;要么一起被撤销,对数据库不做任何的改变
我理解的是事务是维持数据库中数据的完整性和一致性的必要条件。
每当谈起事务最经典的例子就是银行账户之间的汇款转账操作。这必须是一个原子性的操作。
整个操作在数据库中分为三个过程:
银行从甲方取出钱;
银行把钱存入乙方;
在事务日志中记录该事务
这个交易过程,看做一个事务,如果操作失败,事务就会回滚,所有操作都会撤销,目标账户和源账户上的钱都不会改变;操作成功那么就会被永久提交,目标账户和源账户上的金额都改变了。所以说根据这个例子好好理解一下事务,就是一组操作看做一个整体,要是有一个操作失败了,那就从头来过,不可能说从甲方弄出钱去,还没到乙那失败了,甲方这钱也回不来了,这是不存在的,要是这个整体都成功了,那就成既定事实了,甲方的余额就会减少,乙方的余额就会增多。
事务大概理解了,那到底什么情况才是事务呢?这时候就要看看事务的特性:
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进行操作
死锁与锁等待不同,它是锁等待的一个特例,通常发生在两个或多个会话之间。假如一个会话想要修改两个资源对象,可以是表也可以是字段,修改这两个资源的操作在一个事务当中。当它修改第一个对象时需要对其锁定,然后等待第二个对象,这时如果另外一个会话也需要修改这两个资源对象,并且易筋经获得并锁定了第二个对象,那么就会出现思索,因为当前会话锁定了第一个对象等待第二个对象,而另一个会话锁定了第二个对象等待第一个对象