详细文档:http://docs.oracle.com/cd/E11882_01/server.112/e41084/statements_10005.htm#SQLRF01705
语法:
set_transaction::=
C:\>sqlplus "/as sysdba" SQL*Plus: Release 10.2.0.1.0 - Production on 星期三 3月 26 21:53:36 2014 Copyright (c) 1982, 2005, Oracle. All rights reserved. 连接到: Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production With the Partitioning, OLAP and Data Mining options SQL> SELECT XIDUSN, XIDSLOT, XIDSQN, USED_UBLK, USED_UREC, NAME FROM V$TRANSACTION; 未选定行 SQL> SELECT * FROM SCOTT.DEPT; DEPTNO DNAME LOC ---------- -------------- ------------- 10 ACCOUNTING NEW YORK 20 RESEARCH DALLAS 30 SALES CHICAGO 40 OPERATIONS BOSTON SQL> SET TRANSACTION NAME 'TRAN UPDATE'; 事务处理集。 SQL> SELECT XIDUSN, XIDSLOT, XIDSQN, USED_UBLK, USED_UREC, NAME FROM V$TRANSACTION; 未选定行 SQL> UPDATE SCOTT.DEPT SET DNAME='SALES1' WHERE DEPTNO=30; 已更新 1 行。 SQL> SELECT NAME FROM V$TRANSACTION; NAME -------------------------------------------------------------------------------- TRAN UPDATE SQL> ROLLBACK; 回退已完成。 SQL> SELECT NAME FROM V$TRANSACTION; 未选定行 SQL>
对于非SYS用户,只支持SELECT、LOCK TABLE、SET ROLE、ALTER SESSION、ALTER SYSTEM。例如:
SQL> SET TRANSACTION READ ONLY; 事务处理集。 SQL> SELECT * FROM TB_USER; ID USER_NAME USER_AGE ---------- -------------------- ---------- 628 user1 21 630 user3 23 SQL> UPDATE TB_USER SET USER_AGE=31 WHERE ID=628; UPDATE TB_USER SET USER_AGE=31 WHERE ID=628 * 第 1 行出现错误: ORA-01456: 不能在 READ ONLY 事务处理中执行插入/删除/更新操作 SQL>
设置成READ WRITE后就可以了:
SQL> SET TRANSACTION READ WRITE; SET TRANSACTION READ WRITE * 第 1 行出现错误: ORA-01453: SET TRANSACTION 必须是事务处理的第一个语句 SQL> COMMIT; 提交完成。 SQL> SET TRANSACTION READ WRITE; 事务处理集。 SQL> SELECT * FROM TB_USER; ID USER_NAME USER_AGE ---------- -------------------- ---------- 628 user1 21 630 user3 23 SQL> UPDATE TB_USER SET USER_AGE=31 WHERE ID=628; 已更新 1 行。 SQL>
用SYS用户登录:
C:\>SQLPLUS "/AS SYSDBA" SQL*Plus: Release 10.2.0.1.0 - Production on 星期四 3月 27 20:38:27 2014 Copyright (c) 1982, 2005, Oracle. All rights reserved. 连接到: Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production With the Partitioning, OLAP and Data Mining options SQL> SELECT * FROM SCOTT.DEPT; DEPTNO DNAME LOC ---------- -------------- ------------- 10 ACCOUNTING NEW YORK 20 RESEARCH DALLAS 30 SALES CHICAGO 40 OPERATIONS BOSTON SQL> SET TRANSACTION READ ONLY; 事务处理集。 SQL> UPDATE SCOTT.DEPT SET LOC='BOSTON1' WHERE DEPTNO=40; 已更新 1 行。 SQL> SELECT * FROM SCOTT.DEPT; DEPTNO DNAME LOC ---------- -------------- ------------- 10 ACCOUNTING NEW YORK 20 RESEARCH DALLAS 30 SALES CHICAGO 40 OPERATIONS BOSTON1 SQL> ROLLBACK; 回退已完成。 SQL> SELECT * FROM SCOTT.DEPT; DEPTNO DNAME LOC ---------- -------------- ------------- 10 ACCOUNTING NEW YORK 20 RESEARCH DALLAS 30 SALES CHICAGO 40 OPERATIONS BOSTON SQL>
默认是READ COMMITTED。
起两个事务,对于事务A,执行:
SQL> UPDATE DEPT SET LOC='BOSTON1' WHERE DEPTNO=40; 已更新 1 行。
对于事务B,执行:
SQL> UPDATE DEPT SET LOC='BOSTON2' WHERE DEPTNO=40;
此时在事务A执行SELECT:
SQL> SELECT * FROM DEPT; DEPTNO DNAME LOC ---------- -------------- ------------- 10 ACCOUNTING NEW YORK 20 RESEARCH DALLAS 30 SALES CHICAGO 40 OPERATIONS BOSTON1 SQL>
SQL> SELECT * FROM DEPT; DEPTNO DNAME LOC ---------- -------------- ------------- 10 ACCOUNTING NEW YORK 20 RESEARCH DALLAS 30 SALES CHICAGO 40 OPERATIONS BOSTON2
然后事务B执行COMMIT,于是两个结果都一样了,变成了:
SQL> SELECT * FROM DEPT; DEPTNO DNAME LOC ---------- -------------- ------------- 10 ACCOUNTING NEW YORK 20 RESEARCH DALLAS 30 SALES CHICAGO 40 OPERATIONS BOSTON2 SQL>
开启两个事务,对于事务A,执行:
SQL> SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; 事务处理集。 SQL> SELECT * FROM DEPT; DEPTNO DNAME LOC ---------- -------------- ------------- 10 ACCOUNTING NEW YORK 20 RESEARCH DALLAS 30 SALES CHICAGO 40 OPERATIONS BOSTON
SQL> SELECT * FROM DEPT; DEPTNO DNAME LOC ---------- -------------- ------------- 10 ACCOUNTING NEW YORK 20 RESEARCH DALLAS 30 SALES CHICAGO 40 OPERATIONS BOSTON SQL> UPDATE DEPT SET LOC='BOSTON2' WHERE DEPTNO=40; 已更新 1 行。 SQL> COMMIT; 提交完成。 SQL> SELECT * FROM DEPT; DEPTNO DNAME LOC ---------- -------------- ------------- 10 ACCOUNTING NEW YORK 20 RESEARCH DALLAS 30 SALES CHICAGO 40 OPERATIONS BOSTON2 SQL>
再在事务A执行:
SQL> SELECT * FROM DEPT; DEPTNO DNAME LOC ---------- -------------- ------------- 10 ACCOUNTING NEW YORK 20 RESEARCH DALLAS 30 SALES CHICAGO 40 OPERATIONS BOSTON
当一个事务需要更新数据并进行可重复读取时就需要使用序列化事务。
用于回滚。一般不推荐使用。最好使用数据库的自动回滚模式。