1、会话和事务的区别:

1)会话(session):

会话,即session,当你使用工具如sqlplus或者SQLdevelpoer执行连接,连接到某个数据库的时候,就开启了一个会话,直到你关闭这次连接,这个会话才算结束。

2)事务(transaction):

        是一个由多条SQL语句组成的工作逻辑单元,这些语句要么全部执行成功,要么全部不执行。只有commit,rollback,或者关闭工具的情况下,事务才会结束。当一个事务结束之后,下一个可执行的SQL语句自动开启一个新的事务。事务具有4个属性:原子性,一致性,隔离性,持久性。这里不具体说。

以上解释了什么是会话和事务,接下来用一个生动的例子来进一步说明它们俩的区别,相信大家就都能明白了。

比如你去银行办理业务,当你坐在柜台前跟工作人员面对面,开始办理业务的时候,这个时候‘会话’就开启了,那么这个‘会话’结束自然就是你办理好了所有的业务离开柜台的时候。在办理业务的时候,比如你要先办一张银行卡,然后再往里面存一万块钱,那么这就相当于两个事务,一个是办理银行卡,一个是存钱。当你拿到银行卡的时候,相当于这个事务已经commit了,事务结束。当你开始存钱的时候,一个新的事务开启,存进去之后,第二个事务结束。

综上,一个会话可以包含很多个事务,会话是一次对数据库的连接,事务是一个工作单元。

2、事务的提交和回滚:

要永久性的记录事务中SQL语句的结果,需要执行 commit 语句,从而提交(commit)事务。要取消SQL语句的结果,需要执行 rollback 语句,从而回滚事务。rollback 语句可以将行重新设置回原始状态,在执行回滚操作之前对数据库进行的任何修改操作都会被取消,条件是在此之前没有断开与数据库的连接。

3、事务的开始与结束:

1)事务的开始:

·  连接到数据库上,并执行第一条DML语句。

· 前一个事务结束后,又输入了另外一个DML语句。

2)事务的结束:

· 执行 commit 或者 rollback 语句 。

· 执行一条 DDL 语句,例如 create table 语句;在这种情况下,会自动欧诺个执行 commit 语句。

· 执行一条 DCL 语句,例如 grant 语句;在这种情况下,会自动执行 commit 语句。

· 断开与数据库的的连接。在退出 SQL*Plus时,通常会输入 exit 命令,此时会自动执行 commit 语句。如果 SQL*Plus被以外终止了(例如运行SQL*Plus的计算机崩溃了),那么就

  会自动执行 rollback 语句。这适合于任何会访问数据库的程序。例如,如果编写了一个可以访问数据库的Java程序,而这个程序崩溃了,那么就会自动执行 rollback 语句。

· 执行了一条 DML 语句,该语句却失败了;在这种情况下,会为这个无效的 DML 语句执行 rollback 语句。

提示:

事务完成之后,如果不显示的提交或者回滚事务,都被认为是不好的编程习惯,因此确保在每个事务后面都要执行 commit 或者 rollback 语句。

4、保存点:

在事务中的任何地方都可以设置一个保存点(savepoint),这样就可以将修改回滚到保存点处。如果有一个非常大的事务,这将非常的有用,因为这样如果在保存点后进行了误操作,并不需要将整个事务一致回滚到最开头。保存点不能肆意乱用,最好是重新调整一下是事务的结构。将其转换为较小的事务。

select product_id,price from products where product_id in (1,2) ;

update  products set price = price * 1.2 where product_id = 1 ;

//在此处设置一个保存点,将其命名为 save1
svaepoint save1 ;

update  products set price = price * 1.3 where product_id = 2 ;

select product_id,price from products where product_id in (1,2) ;

//将这个事务回滚到刚才设置的保存点处:
rollback to savepoint save1 ;

而 rollback 会将这个事务一致回滚到事务的开始处,取消所有的修改。

5、事务的ACID特性:

数据库理论对事务采取去了更严格的定义,是说明事务有4个基本的特性。称为ACID特性:

  • 原子性(atomicity):事务必须成组的提交或者回滚,因此事务是原子的,这就是说一个事务中包含的的所有SQL语句都是一个不可分割的单元。
  • 一致性(consistency):事务必须确保数据库的状态保持一致,这就是说事务开始时,数据库的状态是一致的;在事务结束时,数据库的状态也必须是一致的。
  • 隔离性(isolation):多个事务可以独立运行,而不会彼此产生影响。
  • 持久性(durability):一旦事务被提交之后,数据库的变化会被永久的保留下来。即使运行数据库软件的机器后来奔溃也是如此。

Oracle数据库软件确保每个事务都具有ACID特性,并且具有非常丰富恢复特性,可以再机器由于各种原因奔溃时恢复数据。

6、并发事务:

Oracle数据库支持多个用户同时与数据库进行交互,每个用户都可以同时运行自己的事务。这种事务就称为并发事务(concurrent transaction)。

如果用户同时运行多个事务,而这些事务都对同一个表产生影响,那么这些事物的影响都是独立的,知道执行一条 commit 语句时才会彼此产生影响。

7、事务锁:

要支持并发事务,Oracle数据库就必须确保表中的数据一只有效。这可以通过锁(lock)来实现。考虑下面的这个例子:两个事务 T1 和 T2 修改 customers 表中顾客#1的记录:

                  1)T1 执行一条 UPDATE 语句修改顾客 #1 的记录,但是 T1 并没有执行 commit 语句。此时就称为 T1 对改行进行了 “加锁”  了。

                  2)T2 也试图执行一条 UPDATE 语句修改顾客 #1 的记录,但是由于改行早已被 T1 加锁了,因此 T2 就不能获得改行的锁。T2 的 UPDATE 语句必须一直等,知道 T1 结束

                        并释放改行的锁为止。

                 3)T1 执行 commit 语句并结束,从而释放改行上的锁。

                 4)T2 获得该行上的锁,并执行 UPDATE 语句。T2获得该行上的锁后一直持有,知道 T2 结束为止。

当一个事务已经拥有某一行上的锁时,另外一个事务不能获得该行上的锁。

注意:

        理解默认的加锁机制的最简单的方法如下:读程序(reader)不会阻塞读程序;写程序(writer)不会阻塞读程序;只有在试图对相同的行进行修改的时,写程序才会阻塞写程

        序。

8、事务隔离级别

事务隔离性级别(transaction isolation level)是一个事务对数据库的修改与并行的另外的一个事务的隔离程度。

  • 幻象读取(phantom read):

事务 T1 读取一条指定的 where 子句所返回的结果集。然后事务 T2 插入一行记录,这行记录恰好可以满足 T1 所使用的查询中的 where 子句的条件。然后 T1 又使用相同的查询再

次对表进行检索,但是此时却看到了事务 T2 刚才插入的新的行。这个新行就称为“幻象”,因为对 T1 来说这一行就像突然出现的一样。

  • 不可重复读取(nonrepeatabl read):

事务 T1 读取一行记录,紧接着事务 T2 修改了 T1 刚才读取的那一行记录的内容。然后 T1 又再次读取了这一行的记录,发现它与刚才读取的结果不同了。这种现象称为“不可重复”

读,因为 T1 原来读取的那一行记录已经发生了变化。

  • 脏读(dirty read):

  事务 T1 更新了 一行记录的内容,但是并没有提交所做的修改。事务 T2 读取更新后的行。然后 T1 执行回滚操作,取消了刚才所做的修改。现在 T2 所读取的行也就无效(也称为

“脏”数据了),因为在 T2 读取这行记录的时候,T1所做的修改并没有提交。

为了处理这些可能出现的问题,数据库实现了不同级别的事务隔离性,以防止并发事务会相互影响。

  1. read uncommitted  幻象读、不可重复读和脏读都允许。
  2. read committed   允许幻象读和不可重复读,但是不允许脏读。
  3. repeatable read  允许幻象读,但是不允许不可重复读和脏读。
  4. serializable  幻象读、不可重复读和脏读都不允许。

Oracle数据库支持 read committed 和 serializable 两种事务隔离性级别,不支持read uncommitted 和 repeatable read 这两种隔离性级别。虽然SQL标准所定义的默认的事务隔离级别是 serializable ,但是数据库默认使用的事务隔离级别却是 read committed ,这几户对所有的程序来说都是可接受的。

警告:

虽然Oracle是数据库也可以使用 serializable 的事务隔离型级别,但是这会增加SQL语句执行所需要的时间,因此只有在必须的情况下才应该使用 serializable 级别。

事务隔离性级别可以使用 set transaction 语句设置,例如,下面的这个语句就将事务的隔离性级别设置为 serializable 级别:
set transaction isolation level serializable  ;