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处理程序,它不会回滚。 所以我更喜欢使用保存点的显式方法。

BEGINEND块是PL / SQL的构build块,每个PL / SQL单元至less包含在一个这样的块中。 在PL / SQL块中嵌套BEGINEND块通常是为了捕获某些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的默认行为。