Oracle 事务处理
1)事务的提交和回滚
要永久性地记录事务中地SQL语句地结果,需要执行COMMIT语句,从而提交事务。
可以运行两个SQL*Plus窗口(即两个事务),当在一个窗口中执行INSET 语句对一个表进行操作,而没有COMMIT语句, 在该窗口查询出的数据是Insert后的数据。而在另一个窗口中查询不出数据已经变化过了,因为数据并没有提交。
2)保存点
在事务中地任何地方都可以设置一个保存点(savepoint),这样可以将修改回滚到保存处。
UPDATE products SET price = price *1.20 WHERE product_id = 4
设置一个保存点,并将其命名为save1
SAVEPOINT save1
UPDATE products SET price = price *1.30 WHERE product_id = 4
这是产品价格又增加了30%,但是如果执行ROLLBACK TO SAVEPOINT save1
产品的价格会回到增加20%的状态。
3)事务锁
当一个事务已经拥有某一行上的锁时,另外一个事务不能获得改行上的锁。也可以这样理解,读程序不会阻塞读程序,写程序不会阻塞读程序,只有在试图对相同的行进行修改时,写程序才会阻塞写程序。
SQL标准定义了以下几种事务的隔离级别,按照隔离级别从低到高依次为:
READ UNCOMMITTED 幻想读,不可重复读和脏读都允许
READ COMMITTED 允许幻想读和不可重复读,但是不允许脏读
REPEATABLE READ 允许幻想读,但是不允许不可重复读和脏读
SERIALIZABLE幻想读,不可重复读和脏读都不允许
Oracle数据库支持READ COMMITTED和SERIALIZABLE两种事务隔离级别,不支持READ COMMITTED和REPEATABLE READ两种事务隔离级别,但是默认使用的事务隔离级别是READ COMMITTED,下表显示了SERIALIZABLE 级别事务的例子
事务1 T1(READ COMMITTED 级别) |
事务2 T2(SERIALIZABLE 级别) |
|
(1) SET TRANSACION ISOLATION LEVEL SERIALIZABLE |
(3) SELECT * FROM customers |
(2) SELECT * FROM customers |
(4) INSERT INTO cusomers VALUES(8,’Steve’,’Button’) |
|
(5) UPDATE customers SET last_name=’Herry’ WHERE customer_id = 3 |
|
(6) COMMIT |
|
(7) SELECT * FROM customers 返回的结果集中包含插入的新行和修改后的结果。 |
(8) SELECT * FROM customers 返回的结果集中仍然不包含事务T1所插入的新行和修改后的结果。因为T2是SERIALIZABLE 级别 |
4)查询闪回
如果错误得提交了修改结果,并想查看被修改行原来得值,可以使用查询闪回(query flashback)。
UPDATE products SET price = price *0.75
WHERE product_id <=5;
COMMIT;
EXECUTE DBMS_FLASHBACK.ENABLE_AT_TIME(SYSDATE-10/1440)
现在再执行任何查询都将显示10分钟之前得状态。假设在刚才得10分钟之内执行了一条UPDATE语句,那么下面这个查询就会显示更新之前得价格。
SELECT * FROM products WHERE product_id <=5
要禁用闪回操作,可以执行DBMS_FLASHBACK.DISABLE(),在再次启用闪回操作之前,必须将其禁用。
(DBMS_* 必须用sys或system账号执行,否则会报错)
5)oracle 使用DBMS_FLASHBACK恢复意外删除的数据 dbms_flashback
1> 获得当前SCN
select dbms_flashback.get_system_change_number from dual;
SQL> select dbms_flashback.get_system_change_number from dual;