PL/SQL 事务处理(Transaction Processing)
来源:互联网 发布:严重的网络暴力事件 编辑:程序博客网 时间:2024/05/16 10:17
-- Start
开启事务
当执行一组 SQL 语句的时候,Oracle 会自动帮我们开启一个事务。我们也可以通过 SET TRANSACTION 语句手动开启一个事务,下面是一个简单的例子。
BEGIN-- 手动开启事务 tranSET TRANSACTION NAME 'tran';--SET TRANSACTION READ WRITE NAME 'tran'; -- 这条语句和上面的语句完全相同,表明它是一个读写事务INSERT INTO TEST VALUES ('Scott');COMMIT; -- 提交事务END;/
-- 我们可以设置事务为只读事务,这在生成报告,账单等时特别有用SET TRANSACTION READ ONLY NAME 'tran';SELECT * FROM TEST;COMMIT; -- 提交事务,只读事务也需要提交的哦-- 我们还可以指定事务的隔离级别SET TRANSACTION ISOLATION LEVEL SERIALIZABLE NAME 'tran';-- SET TRANSACTION ISOLATION LEVEL READ COMMITTED NAME 'tran'; -- 事务默认的隔离级别是 READ COMMITTEDSELECT * FROM TEST;COMMIT; -- 提交事务-- 我们还可以指定当事务失败时,将事务回滚到指定的回滚段-- Oracle 不推荐我们这样做,尽量使用自动回滚SET TRANSACTION USE ROLLBACK SEGMENT test NAME 'tran';INSERT INTO TEST VALUES ('Scott');ROLLBACK; -- 回滚事务
提交事务
Oracle 使用 COMMIT 语句提交事务,它也有许多参数,让我们可以根据不同的情况,对提交事务进行更精准的控制。
INSERT INTO TEST VALUES ('Scott');COMMIT; -- 提交事务COMMIT COMMENT 'test'; -- COMMENT 语句为事务添加注释,但Oracle不推荐我们使用它,它的存在是为了向后兼容。COMMIT WORK; -- COMMIT 和 COMMIT WORK 完全等价COMMIT WRITE WAIT IMMEDIATE; -- 这条语句和上面的语句完全相同COMMIT WRITE WAIT BATCH;COMMIT WRITE NOWAIT BATCH;COMMIT WRITE NOWAIT IMMEDIATE;
上面的语句中出现了几个关键字 WRITE,WAIT,NOWAIT,IMMEDIATE 和 BATCH。那么它们是什么意思呢?这还要从 Oracle 是如何保证事务一致性说起。通常,Oracle 会先写入日志,然后提交事务,如果事务在提交的过程中挂了,Oracle 会根据日志来恢复数据库,如果事务提交成功了,Oracle 会返回成功的消息。上面的语句中 WAIT 表示等待日志输入完成,然后返回成功的消息。NOWAIT 表示不等待日志输入完成就返回给成功的消息。IMMEDIATE 表示立刻输出日志到磁盘,BATCH 表示批量输出日志到磁盘。所以下面的语句表示批量输出日志到磁盘,但不等输出日志完成就返回给成功的消息。这样可以极大的提高性能,但是是有风险的,在极端情况下,事务失败了,但用户收到了事务提交成功的消息。
COMMIT WRITE NOWAIT BATCH;
此外,我们还可以为 COMMIT 添加 FORCE 语句,它可以让我们对分布式事务进行手动控制。更多信息参见 Oracle 手册。
回滚事务
Oracle 使用 ROLLBACK 来回滚事务。
ROLLBACK;ROLLBACK WORK; -- ROLLBACK 和 ROLLBACK WORK 完全相同ROLLBACK TO SAVEPOINT test; -- 回滚到指定的回滚点ROLLBACK FORCE '25.32.87'; -- FORCE 语句用来手动控制分布式事务回滚。
回滚点
Oracle 使用 SAVEPOINT 来设置回滚点。
INSERT INTO TEST VALUES ('Scott');SAVEPOINT sp1;INSERT INTO TEST VALUES ('Tom');ROLLBACK TO SAVEPOINT sp1; -- 回滚到sp1,'Tom' 记录会被回滚COMMIT;
手动加锁(LOCK TABLE)
通常,Oracle 会根据需要自动锁定表或行,如果我们要对一个表的大部分记录进行操作,锁定每一行会严重消耗系统资源,这个时候我们可以通过 LOCK TABLE 语句手动锁定整个表。例如下面的语句表示使用 EXCLUSIVE 模式锁定 TEST 表,如果其他事务已经锁定了该表,立刻返回。
-- EXCLUSIVE 表示使用独占模式锁定表,其他事务只允许读表。-- NOWAIT 表示如果其他事务已经锁定了该表,立刻返回。LOCK TABLE TEST IN EXCLUSIVE MODE NOWAIT;
SELECT FOR UPDATE
如果我们查询某些记录是为了更新它,那么我们可以给 SELECT 语句加上 FOR UPDATE 子句,这样 Oracle 会返回结果的同时锁定它,从而防止别人更新这些记录, 下面是一个简单的例子。
DECLARE CURSOR c1 IS SELECT employee_id, salary FROM employees FOR UPDATE OF salary; BEGIN NULL;END;
自主事务
通常,如果子程序 A 调用 B,那么 A 和 B 将在同一个事务中,A 或 B 中的任意一个 COMMIT 语句将会使 A 和 B 所做的所有更改全部提交。有时候,这不是我们想要的结果,我们想让 B 在自己的事务中,无论 A 成功或失败都不影响 B,怎么办?很简单,我们只需在 B 的申明部分加上 PRAGMA AUTONOMOUS_TRANSACTION 语句即可,怎么样,简单吧,下面是一个简单的例子。
-- 存储过程 B CREATE OR REPLACE PROCEDURE INSERT_LOG ( MESSAGE VARCHAR2 ) IS -- 表示该存储过程是一个自主事务存储过程 PRAGMA AUTONOMOUS_TRANSACTION; BEGIN INSERT INTO LOG VALUES (MESSAGE); COMMIT; END; -- 存储过程 A CREATE OR REPLACE PROCEDURE INSERT_EMPLOYEE ( FIRST_NAME VARCHAR2, LAST_NAME VARCHAR2, SALARY NUMBER ) IS BEGIN -- 开启事务 COMMIT; SET TRANSACTION NAME 'tran'; -- 设置回滚点 SAVEPOINT sp1; -- 调用存储过程 INSERT_LOG('Inserting EMPLOYEES'); INSERT INTO EMPLOYEES VALUES (NULL, FIRST_NAME, LAST_NAME, SALARY, CURRENT_TIMESTAMP); EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('ERROR CODE:' || SQLCODE || ', ERROR MESSAGE: ' || SQLERRM); ROLLBACK TO sp1; -- 回滚 END; -- 测试 DECLARE FIRST_NAME VARCHAR2(20) := 'BO'; LAST_NAME VARCHAR2(20) := 'SHANG'; BEGIN INSERT_EMPLOYEE(FIRST_NAME, LAST_NAME, 8888.88); END;
--更多参见:Oracle PL/SQL 精萃
-- 声明:转载请注明出处
-- Last Edited on 2015-06-02
-- Created by ShangBo on 2015-01-29
-- End
- PL/SQL 事务处理(Transaction Processing)
- PL/SQL 的 事务处理
- SQL SERVER 之 transaction 事务处理
- On-Line Transaction Processing联机事务处理系统(OLTP)
- TPC(Transaction Processing Performance Council)-事务处理性能委员会
- SQL Server数据库事务处理详解 TRANSACTION
- 数据库中的事务处理详解SQL Server Transaction
- 事务处理Transaction
- 事务处理Transaction
- 事务处理(Transaction)
- 事务处理 Transaction
- Oracle PL/SQL之SET TRANSACTION READ ONLY(事务隔离性)
- Oracle PL/SQL之SET TRANSACTION READ ONLY(事务隔离性)
- Oracle PL/SQL开发基础(第二十七弹:事务处理简介)
- Transaction Processing Middleware
- Distributed Transaction Processing:mysql
- C#中實現Transaction事务处理
- C#中實現Transaction事务处理
- ubuntu Samba服务搭建 供windows共享
- 【POJ】3744 Scout YYF I (概率DP+矩阵优化)
- Android APK反编译就这么简单 详解(附图)
- 判别式模型与生成式模型(二)
- unigine学习(2)——编译unigine2012
- PL/SQL 事务处理(Transaction Processing)
- const关键字
- Centos 6.5双网卡绑定实现冗余
- JS理解
- linux系列文章之linux介绍
- iOS INVALID_USER_SCODE 定位 用户安全码未通过
- 老项目在Xcode6调试运行时报错的问题(App installation failed).
- day02-JAXP DOM
- 字符编码、单字节字符编码、双字节字符编码、多字节字符编码