在数据库管理中,事务控制是一个核心概念。它确保数据的完整性和一致性。不同的数据库系统对事务控制的实现各不相同。本文将探讨Oracle数据库中事务控制的机制,以及它与SQL标准的差异。
在SQL标准中,事务控制语句如START TRANSACTION、END TRANSACTION和SAVE TRANSACTION定义了事务的开始和结束。不同的数据库系统根据自己的需求实现这些语句。例如,Informix数据库使用BEGIN [WORK]语句来标记事务块的开始。当执行显式的COMMIT或ROLLBACK,或者SQL异常结束时,事务块结束。
在非Oracle数据库(例如Informix)中,事务块可能如下所示:
SQL BEGIN [WORK]
INSERT…
UPDATE…
DELETE…
COMMIT [WORK];
在Oracle数据库中,没有BEGIN [WORK]等价的语句。当第一个可执行语句对数据库进行更改时,就隐式地开始了事务块。这包括DML(数据操作语言)和DDL(数据定义语言)语句。
因此,在Oracle中,上述语句块将被写为:
SQL
INSERT…
UPDATE…
DELETE…
COMMIT [WORK];
在Oracle中,当执行第一个DML(例如INSERT)语句时,隐式事务块就开始了,并且不是通过显式的BEGIN或START关键字开始的。另一方面,Oracle中的COMMIT或ROLLBACK确实标志着事务的结束。(在某些情况下,事务也可能隐式结束。例如,DDL语句参与隐式事务)。
然而,肯定在Oracle中看到过BEGIN(和END)关键字。是的,是对的,这个关键字确实存在,但它是PL/SQL中的语句,而不是普通的SQL。PL/SQL是Oracle中的一个单独的编程语言,就像C或Java一样,只是PL/SQL专门用于更有效地处理SQL。
如果不熟悉Oracle,可能会将PL/SQL中的BEGIN语句与其它数据库中的BEGIN [WORK]混淆。PL/SQL中的BEGIN…END块仅仅是一系列语句(SQL和非SQL)的语法集合。它们与事务无关。然而,由于BEGIN…END块中的一系列SQL语句标记了一个单一的PL/SQL语句,因此在PL/SQL块之后的COMMIT(或ROLLBACK)可能会提交(或回滚)PL/SQL块中的所有SQL语句,从而暗示BEGIN与新事务有关。事实并非如此!假设在COMMIT之前有多个PL/SQL块(BEGIN…END),那么这两个块中的语句都会被提交。如果在第一个PL/SQL块结束时停止(标记为第一个"/"),那么它还没有被提交。
SQL
-- PLSQL Block 1
BEGIN
<SQL statements>
END;
/
-- PLSQL Block 2
BEGIN
<SQL Statements>
END;
/
COMMIT;