BEGIN – END在PL / SQL中阻止primefaces事务
这个信息应该很容易find,但我没有任何运气。
当我在PL / SQL中有一个BEGIN - END
块时,它是否像一个primefaces事务一样行事,它将尝试在END
块上提交,如果出现任何错误,则回滚这些更改?
如果不是,我如何确保BEGIN – END块内的代码像primefaces事务一样运行,块如何默认运行?
编辑:我正在运行从存储过程,我想用隐式块。
首先, BEGIN..END
只是句法元素,与交易无关。
其次,在Oracle中,所有单独的DML语句都是primefaces的(即,它们要么全部成功,要么在第一次失败时回滚任何中间变化)(除非使用EXCEPTIONS INTO选项,这里我不介绍)。
如果你希望一组语句被视为一个单一的primefaces事务,你可以这样做:
BEGIN SAVEPOINT start_tran; INSERT INTO .... ; -- first DML UPDATE .... ; -- second DML BEGIN ... END; -- some other work UPDATE .... ; -- final DML EXCEPTION WHEN OTHERS THEN ROLLBACK TO start_tran; RAISE; END;
这样,任何exception都会导致该块中的语句被回滚,但在此块之前运行的任何语句都不会被回滚。
请注意,我不包括COMMIT – 通常我更喜欢调用过程来发出提交。
确实,BEGIN..END块没有exception处理程序会自动为您处理:
BEGIN INSERT INTO .... ; -- first DML UPDATE .... ; -- second DML BEGIN ... END; -- some other work UPDATE .... ; -- final DML END;
如果发生exception,则所有插入和更新都将回滚; 但只要你想添加一个exception处理程序,它不会回滚。 所以我更喜欢使用保存点的显式方法。
BEGIN
– END
块是PL / SQL的构build块,每个PL / SQL单元至less包含在一个这样的块中。 在PL / SQL块中嵌套BEGIN
– END
块通常是为了捕获某些exception并处理该特殊exception,然后引发不相关的exception。 不过,在PL / SQL中,您(客户端)必须始终为事务发出提交或回滚。
如果您希望在包含PL / SQL的事务中执行primefaces事务,则需要在声明块中声明PRAGMA AUTONOMOUS_TRANSACTION
。 这将确保该块内的任何DML可以独立于包含事务而被提交或回滚。
但是,您不能为嵌套块声明此附注。 你只能申明:
- 顶层(非嵌套的)匿名PL / SQL块
- 项目清单
- 本地,独立和打包的function和程序
- SQL对象types的方法
- 数据库触发器
参考: Oracle
你不会提到这是一个匿名的PL / SQL块还是一个声明式的,也就是说。 包,程序或function。 但是,在PL / SQL中,必须显式执行COMMIT以将事务保存到数据库。 COMMIT实际上将所有未保存的事务从当前用户的会话保存到数据库。
如果发生错误,事务隐式地执行ROLLBACK。
这是PL / SQL的默认行为。