如何声明一个事务的开始(100分)

时间:2022-09-12 21:25:59
环境:windows xp , oracle 9i
在sqlplus中想执行如下语句
SET TRANSACTION;
INSERT INTO CUSTOMERS VALUES("Bubba MacDowell", "2222 Blue Lake Way", "Austin", "TX", 39874, 8);
ROLLBACK;
只输入了SET TRANSACTION;
报如下错误
第 1 行出现错误:
ORA-00900: 无效 SQL 语句
请指导,如何声明一个事务的开始,注意不是只读事务,也没有使用回滚段(ROLLBACK SEGMENT )?谢谢

30 个解决方案

#1


引用楼主 a13951845000 的帖子:
环境:windows xp , oracle 9i 
在sqlplus中想执行如下语句 

SET TRANSACTION=;--=后面应该是事务的隔离级别  
INSERT INTO CUSTOMERS VALUES("Bubba MacDowell", "2222 Blue Lake Way", "Austin", "TX", 39874, 8); 
ROLLBACK; 
只输入了SET TRANSACTION; 
报如下错误 
第 1 行出现错误: 
ORA-00900: 无效 SQL 语句 
请指导,如何声明一个事务的开始,注意不是只读事务,也没有使用回滚段(ROLLBACK SEGMENT )?谢谢

--看注释后面

#3


引用 1 楼 fuyou001 的回复:
引用楼主 a13951845000 的帖子:
环境:windows xp , oracle 9i 
在sqlplus中想执行如下语句 

SET TRANSACTION=;--=后面应该是事务的隔离级别  
INSERT INTO CUSTOMERS VALUES("Bubba MacDowell", "2222 Blue Lake Way", "Austin", "TX", 39874, 8); 
ROLLBACK; 
只输入了SET TRANSACTION; 
报如下错误 
第 1 行出现错误: 
ORA-00900: 无效 SQL 语句 
请指导,如何声明一个事务的开始,注意不是只读事务,也没有使用回滚段…

sorry,记错了
一个完整的例子
http://www.bitscn.com/pdb/oracle/200806/143859.html

#4



1、 什么是事务 

事务是作为单个逻辑工作单元执行的一系列操作。一个逻辑工作单元必须有四个属性,称为 ACID(原子性、一致性、隔离性和持久性)属性,只有这样才能成为一个事务: 

原子性:事务必须是原子工作单元;对于其数据修改,要么全都执行,要么全都不执行。 

一致性:事务在完成时,必须使所有的数据都保持一致状态。在相关数据库中,所有规则都必须应用于事务的修改,以保持所有数据的完整性。事务结束时,所有的内部数据结构(如 B 树索引或双向链表)都必须是正确的。 

隔离性:由并发事务所作的修改必须与任何其它并发事务所作的修改隔离。事务查看数据时数据所处的状态,要么是另一并发事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查看中间状态的数据。这称为可串行性,因为它能够重新装载起始数据,并且重播一系列事务,以使数据结束时的状态与原始事务执行的状态相同。 

持久性:事务完成之后,它对于系统的影响是永久性的。该修改即使出现系统故障也将一直保持。 

所以,当我们需要进行事务处理时,一定要做好事务划分,即哪些对数据库的操作均完成后才能作为一个事务。 

2、 事务的控制 

oracle没有“开始事务”的语句,事务隐式地开始于第一条修改数据的语句,并以commit或rollback语句显式的结束事务。一条语句要么完全执行,要么完全回滚,一条语句的失败不能使它前面执行的语句自动回滚。 

事务控制语句:commit,rollback,savepoint,rollback to <savepoint>
set transaction:设置不同的事物属性,例如隔离等级和是否只读或可读写,也可以使用此语句来指示事务使用某个特定的回滚段。 

COMMIT是事务提交命令。 

ROLLBACK是事务回滚命令,在尚未提交commit命令之前,如果发现delete、insert和update等操作需要恢复的话,可以使用rollback命令回滚到上次commit时的状态。 

SAVEPOINT是保存点命令。事务通常由数条命令组成,可以将每个事务划分成若干个部分进行保存,这样每次可以回滚每个保存点,而不必回滚整个事务。语法格式如下。
创建保存点:savepoint 保存点名;
回滚保存点:rollback to 保存点名; 

例子: 

 

PROCEDURE VENUSTEST 

IS 

i NUMBER (10); 

a NUMBER (10); 

断点一 

BEGIN 

   COMMIT; 

INSERT INTO alex_test 

VALUES ('Venus', 'Venus' || 'aaa' || 'Feng'); 

INSERT INTO alex_test 

VALUES ('Jessie', 'Jessie' || 'TestA'); 

INSERT INTO alex_test 

VALUES ('Jessie', 'Jessie' || 'TestB'); 

INSERT INTO alex_test 

VALUES ('Jessie', 'Jessie' || 'TestC'); 

断点二 

SAVEPOINT a; 

UPDATE alex_test 

SET testcontents = 'TestBB' 

WHERE testname = 'Jessie' AND testcontents = 'TestB'; 

INSERT INTO alex_test 

VALUES ('Jessie', 'Jessie' || 'TestD'); 

断点三 

SAVEPOINT b; 

DELETE FROM alex_test 

WHERE testname = 'Jessie'; 

断点四 

ROLLBACK TO SAVEPOINT b; 

断点五 

ROLLBACK TO SAVEPOINT a; 

断点六 

ROLLBACK; 

EXCEPTION 

   WHEN OTHERS 

THEN 

      ROLLBACK; 

END; 

运行结果如下: 

执行完“断点一”后,上一个事务已经提交,下面开始的操作属于另一个事务。 

单步执行到“断点二”,将该处的数据保存为一个一个状态,但是没有提交。 

单步执行到“断点三”,将该处的数据保存为一个一个状态,但是没有提交。 

单步执行到“断点四”,将数据库的数据回滚,回滚到“断点三”的状态,这时的数据与执行到“断点三”的数据一样。 

单步执行到“断点五”,将数据库的数据回滚,回滚到“断点二”的状态,这时的数据与执行到“断点二”的数据一样。 

单步执行到“断点六”,将数据库的数据回滚,回滚到“断点一”的状态,这时的数据与执行到“断点一”的数据一样。


http://cid-71957aef70875fdb.spaces.live.com/blog/cns!71957AEF70875FDB!120.entry?sa=591587387

引用楼主 a13951845000 的帖子:
环境:windows xp , oracle 9i 
在sqlplus中想执行如下语句 
SET TRANSACTION; 
INSERT INTO CUSTOMERS VALUES("Bubba MacDowell", "2222 Blue Lake Way", "Austin", "TX", 39874, 8); 
ROLLBACK; 
只输入了SET TRANSACTION; 
报如下错误 
第 1 行出现错误: 
ORA-00900: 无效 SQL 语句 
请指导,如何声明一个事务的开始,注意不是只读事务,也没有使用回滚段(ROLLBACK SEGMENT )?谢谢

#5


另外:
INSERT INTO CUSTOMERS VALUES("Bubba MacDowell", "2222 Blue Lake Way", "Austin", "TX", 39874, 8); 

oracle 中应该使用单引号 
INSERT INTO CUSTOMERS VALUES('Bubba MacDowell', '2222 Blue Lake Way', 'Austin', 'TX', 39874, 8); 

#6


oracle 的 PL/SQL 不同于 sql server 的 TSQL,它没有 begin trans 这样的语句,第一个 sql 语句就是事务的开始。

#7


引用 6 楼 ruihuahan 的回复:
oracle 的 PL/SQL 不同于 sql server 的 TSQL,它没有 begin trans 这样的语句,第一个 sql 语句就是事务的开始。

楼主的意思是ORACLE从第一个SQL语句开始就开始了一个事务?那么这个事务什么时候结束呢?或者说什么时候提交这个事务呢?假如有2个存储过程都对表A进行了数据修改的操作,其中存储过程1在修改了表A的数据后,接着做一个较长时间的别的工作,此时存储过程2是否可以处理表A的数据?按事务的概念,如果存储过程1在修改了表A的数据后,马上提交事务,也就是COMMIT一下,然后再去做下一步工作,此时存储过程2应该是可以接着处理表A的数据的。也就是说尽可能减少锁表的时间,不知道我理解得是否有问题,是否有人能解释下?

#8


引用 4 楼 oracledbalgtu 的回复:
SQL code
1、 什么是事务 

事务是作为单个逻辑工作单元执行的一系列操作。一个逻辑工作单元必须有四个属性,称为 ACID(原子性、一致性、隔离性和持久性)属性,只有这样才能成为一个事务: 

原子性:事务必须是原子工作单元;对于其数据修改,要么全都执行,要么全都不执行。 

一致性:事务在完成时,必须使所有的数据都保持一致状态。在相关数据库中,所有规则都必须应用于事务的修改,以保持所有数据的完整性。事务…

楼主解释得很详细,不错。再问:
如果在每个修改数据的语句 后面使用COMMIT并判断是否提交成功,如果不成功,马上回滚,并退出处理过程,是否可以?当然,看了楼主的解释,我想设置保存点SAVEPOINT的最大好处就是一组修改数据的操作,要么全成功,要么全部作废,不知道是不是这么理解的?如果是的话,这个功能是十分有用的,相对于SQL SERVER的简单COMMIT和ROLLBACK来说,更好控制了

#9


第一个DML操作,包括UPDATE,DELETE,INSERT或MERGE就是事务的开始,COMMIT或ROLLBACK是事务的终止。

#10


我觉得可以不用SET TRANSACTION对事务进行申明了吧
两次commit或rollback之间就是一个事务单位! 

#11


引用 9 楼 zcs_1 的回复:
第一个DML操作,包括UPDATE,DELETE,INSERT或MERGE就是事务的开始,COMMIT或ROLLBACK是事务的终止。


同意。 不过注意除了commit或rollbac这样的DCL之外,像alter table这样的DDL也会导致事务自动提交。

#12


强滴

#13


不需要显示的申明ORACLE事务的开始,在执行DML语句时,稳式的开始了事务,ROLLBACK、COMMIT稳式的始束事务

#14


学习

#15


先谢谢大家

#16


还有补充的吗?

#17


用savepoint

#18


引用 7 楼 antinet 的回复:
假如有2个存储过程都对表A进行了数据修改的操作,其中存储过程1在修改了表A的数据后,接着做一个较长时间的别的工作,此时存储过程2是否可以处理表A的数据?按事务的概念,如果存储过程1在修改了表A的数据后,马上提交事务,也就是COMMIT一下,然后再去做下一步工作,此时存储过程2应该是可以接着处理表A的数据的。也就是说尽可能减少锁表的时间,不知道我理解得是否有问题,是否有人能解释下?

Oracle默认的隔离等级是Read Committed,不禁止其他事务对当前查询正在访问的数据进行修改.
所以如果存储过程1如果修改了数据后,没有Commit,接着做较长时间别的工作,那么存储过程2就会得到错误的数据.
可以修改Oracle的隔离等级Serializable

在事务开始时执行
set transaction isolation level serializable;

#19


#20


还有解释吗?

#21


今天又学习了  事务 

#22


还有解释吗?

#23


再顶

#24


学习了

#25


很详细的解释...

#26


oracle没有 begin trans 这样的语句,第一个 sql 语句就是事务的开始。
以commit或rollback语句显式的结束事务.
也可以用savepoint以将每个事务划分成若干个部分进行保存,这样每次可以回滚每个保存点,而不必回滚整个事务。

#27


#28


up

#29


#30


还有解释吗?

#1


引用楼主 a13951845000 的帖子:
环境:windows xp , oracle 9i 
在sqlplus中想执行如下语句 

SET TRANSACTION=;--=后面应该是事务的隔离级别  
INSERT INTO CUSTOMERS VALUES("Bubba MacDowell", "2222 Blue Lake Way", "Austin", "TX", 39874, 8); 
ROLLBACK; 
只输入了SET TRANSACTION; 
报如下错误 
第 1 行出现错误: 
ORA-00900: 无效 SQL 语句 
请指导,如何声明一个事务的开始,注意不是只读事务,也没有使用回滚段(ROLLBACK SEGMENT )?谢谢

--看注释后面

#2


#3


引用 1 楼 fuyou001 的回复:
引用楼主 a13951845000 的帖子:
环境:windows xp , oracle 9i 
在sqlplus中想执行如下语句 

SET TRANSACTION=;--=后面应该是事务的隔离级别  
INSERT INTO CUSTOMERS VALUES("Bubba MacDowell", "2222 Blue Lake Way", "Austin", "TX", 39874, 8); 
ROLLBACK; 
只输入了SET TRANSACTION; 
报如下错误 
第 1 行出现错误: 
ORA-00900: 无效 SQL 语句 
请指导,如何声明一个事务的开始,注意不是只读事务,也没有使用回滚段…

sorry,记错了
一个完整的例子
http://www.bitscn.com/pdb/oracle/200806/143859.html

#4



1、 什么是事务 

事务是作为单个逻辑工作单元执行的一系列操作。一个逻辑工作单元必须有四个属性,称为 ACID(原子性、一致性、隔离性和持久性)属性,只有这样才能成为一个事务: 

原子性:事务必须是原子工作单元;对于其数据修改,要么全都执行,要么全都不执行。 

一致性:事务在完成时,必须使所有的数据都保持一致状态。在相关数据库中,所有规则都必须应用于事务的修改,以保持所有数据的完整性。事务结束时,所有的内部数据结构(如 B 树索引或双向链表)都必须是正确的。 

隔离性:由并发事务所作的修改必须与任何其它并发事务所作的修改隔离。事务查看数据时数据所处的状态,要么是另一并发事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查看中间状态的数据。这称为可串行性,因为它能够重新装载起始数据,并且重播一系列事务,以使数据结束时的状态与原始事务执行的状态相同。 

持久性:事务完成之后,它对于系统的影响是永久性的。该修改即使出现系统故障也将一直保持。 

所以,当我们需要进行事务处理时,一定要做好事务划分,即哪些对数据库的操作均完成后才能作为一个事务。 

2、 事务的控制 

oracle没有“开始事务”的语句,事务隐式地开始于第一条修改数据的语句,并以commit或rollback语句显式的结束事务。一条语句要么完全执行,要么完全回滚,一条语句的失败不能使它前面执行的语句自动回滚。 

事务控制语句:commit,rollback,savepoint,rollback to <savepoint>
set transaction:设置不同的事物属性,例如隔离等级和是否只读或可读写,也可以使用此语句来指示事务使用某个特定的回滚段。 

COMMIT是事务提交命令。 

ROLLBACK是事务回滚命令,在尚未提交commit命令之前,如果发现delete、insert和update等操作需要恢复的话,可以使用rollback命令回滚到上次commit时的状态。 

SAVEPOINT是保存点命令。事务通常由数条命令组成,可以将每个事务划分成若干个部分进行保存,这样每次可以回滚每个保存点,而不必回滚整个事务。语法格式如下。
创建保存点:savepoint 保存点名;
回滚保存点:rollback to 保存点名; 

例子: 

 

PROCEDURE VENUSTEST 

IS 

i NUMBER (10); 

a NUMBER (10); 

断点一 

BEGIN 

   COMMIT; 

INSERT INTO alex_test 

VALUES ('Venus', 'Venus' || 'aaa' || 'Feng'); 

INSERT INTO alex_test 

VALUES ('Jessie', 'Jessie' || 'TestA'); 

INSERT INTO alex_test 

VALUES ('Jessie', 'Jessie' || 'TestB'); 

INSERT INTO alex_test 

VALUES ('Jessie', 'Jessie' || 'TestC'); 

断点二 

SAVEPOINT a; 

UPDATE alex_test 

SET testcontents = 'TestBB' 

WHERE testname = 'Jessie' AND testcontents = 'TestB'; 

INSERT INTO alex_test 

VALUES ('Jessie', 'Jessie' || 'TestD'); 

断点三 

SAVEPOINT b; 

DELETE FROM alex_test 

WHERE testname = 'Jessie'; 

断点四 

ROLLBACK TO SAVEPOINT b; 

断点五 

ROLLBACK TO SAVEPOINT a; 

断点六 

ROLLBACK; 

EXCEPTION 

   WHEN OTHERS 

THEN 

      ROLLBACK; 

END; 

运行结果如下: 

执行完“断点一”后,上一个事务已经提交,下面开始的操作属于另一个事务。 

单步执行到“断点二”,将该处的数据保存为一个一个状态,但是没有提交。 

单步执行到“断点三”,将该处的数据保存为一个一个状态,但是没有提交。 

单步执行到“断点四”,将数据库的数据回滚,回滚到“断点三”的状态,这时的数据与执行到“断点三”的数据一样。 

单步执行到“断点五”,将数据库的数据回滚,回滚到“断点二”的状态,这时的数据与执行到“断点二”的数据一样。 

单步执行到“断点六”,将数据库的数据回滚,回滚到“断点一”的状态,这时的数据与执行到“断点一”的数据一样。


http://cid-71957aef70875fdb.spaces.live.com/blog/cns!71957AEF70875FDB!120.entry?sa=591587387

引用楼主 a13951845000 的帖子:
环境:windows xp , oracle 9i 
在sqlplus中想执行如下语句 
SET TRANSACTION; 
INSERT INTO CUSTOMERS VALUES("Bubba MacDowell", "2222 Blue Lake Way", "Austin", "TX", 39874, 8); 
ROLLBACK; 
只输入了SET TRANSACTION; 
报如下错误 
第 1 行出现错误: 
ORA-00900: 无效 SQL 语句 
请指导,如何声明一个事务的开始,注意不是只读事务,也没有使用回滚段(ROLLBACK SEGMENT )?谢谢

#5


另外:
INSERT INTO CUSTOMERS VALUES("Bubba MacDowell", "2222 Blue Lake Way", "Austin", "TX", 39874, 8); 

oracle 中应该使用单引号 
INSERT INTO CUSTOMERS VALUES('Bubba MacDowell', '2222 Blue Lake Way', 'Austin', 'TX', 39874, 8); 

#6


oracle 的 PL/SQL 不同于 sql server 的 TSQL,它没有 begin trans 这样的语句,第一个 sql 语句就是事务的开始。

#7


引用 6 楼 ruihuahan 的回复:
oracle 的 PL/SQL 不同于 sql server 的 TSQL,它没有 begin trans 这样的语句,第一个 sql 语句就是事务的开始。

楼主的意思是ORACLE从第一个SQL语句开始就开始了一个事务?那么这个事务什么时候结束呢?或者说什么时候提交这个事务呢?假如有2个存储过程都对表A进行了数据修改的操作,其中存储过程1在修改了表A的数据后,接着做一个较长时间的别的工作,此时存储过程2是否可以处理表A的数据?按事务的概念,如果存储过程1在修改了表A的数据后,马上提交事务,也就是COMMIT一下,然后再去做下一步工作,此时存储过程2应该是可以接着处理表A的数据的。也就是说尽可能减少锁表的时间,不知道我理解得是否有问题,是否有人能解释下?

#8


引用 4 楼 oracledbalgtu 的回复:
SQL code
1、 什么是事务 

事务是作为单个逻辑工作单元执行的一系列操作。一个逻辑工作单元必须有四个属性,称为 ACID(原子性、一致性、隔离性和持久性)属性,只有这样才能成为一个事务: 

原子性:事务必须是原子工作单元;对于其数据修改,要么全都执行,要么全都不执行。 

一致性:事务在完成时,必须使所有的数据都保持一致状态。在相关数据库中,所有规则都必须应用于事务的修改,以保持所有数据的完整性。事务…

楼主解释得很详细,不错。再问:
如果在每个修改数据的语句 后面使用COMMIT并判断是否提交成功,如果不成功,马上回滚,并退出处理过程,是否可以?当然,看了楼主的解释,我想设置保存点SAVEPOINT的最大好处就是一组修改数据的操作,要么全成功,要么全部作废,不知道是不是这么理解的?如果是的话,这个功能是十分有用的,相对于SQL SERVER的简单COMMIT和ROLLBACK来说,更好控制了

#9


第一个DML操作,包括UPDATE,DELETE,INSERT或MERGE就是事务的开始,COMMIT或ROLLBACK是事务的终止。

#10


我觉得可以不用SET TRANSACTION对事务进行申明了吧
两次commit或rollback之间就是一个事务单位! 

#11


引用 9 楼 zcs_1 的回复:
第一个DML操作,包括UPDATE,DELETE,INSERT或MERGE就是事务的开始,COMMIT或ROLLBACK是事务的终止。


同意。 不过注意除了commit或rollbac这样的DCL之外,像alter table这样的DDL也会导致事务自动提交。

#12


强滴

#13


不需要显示的申明ORACLE事务的开始,在执行DML语句时,稳式的开始了事务,ROLLBACK、COMMIT稳式的始束事务

#14


学习

#15


先谢谢大家

#16


还有补充的吗?

#17


用savepoint

#18


引用 7 楼 antinet 的回复:
假如有2个存储过程都对表A进行了数据修改的操作,其中存储过程1在修改了表A的数据后,接着做一个较长时间的别的工作,此时存储过程2是否可以处理表A的数据?按事务的概念,如果存储过程1在修改了表A的数据后,马上提交事务,也就是COMMIT一下,然后再去做下一步工作,此时存储过程2应该是可以接着处理表A的数据的。也就是说尽可能减少锁表的时间,不知道我理解得是否有问题,是否有人能解释下?

Oracle默认的隔离等级是Read Committed,不禁止其他事务对当前查询正在访问的数据进行修改.
所以如果存储过程1如果修改了数据后,没有Commit,接着做较长时间别的工作,那么存储过程2就会得到错误的数据.
可以修改Oracle的隔离等级Serializable

在事务开始时执行
set transaction isolation level serializable;

#19


#20


还有解释吗?

#21


今天又学习了  事务 

#22


还有解释吗?

#23


再顶

#24


学习了

#25


很详细的解释...

#26


oracle没有 begin trans 这样的语句,第一个 sql 语句就是事务的开始。
以commit或rollback语句显式的结束事务.
也可以用savepoint以将每个事务划分成若干个部分进行保存,这样每次可以回滚每个保存点,而不必回滚整个事务。

#27


#28


up

#29


#30


还有解释吗?