首页 > 数据库 >PL / SQL 101:定义和管理事务

PL / SQL 101:定义和管理事务

时间:2023-06-15 11:04:21浏览次数:35  
标签:语句 事务 toy 更改 保存 回滚 SQL 101 PL

订阅专栏

如果您有一个只读数据库,则不必担心事务。但是对于你将要构建的几乎所有应用程序,情况并非如此。因此,交易的概念和管理对于您的应用程序的成功至关重要。


事务是Oracle数据库作为一个单元处理的一个或多个SQL语句的序列:要么执行所有语句,要么都不执行。事务隐含地从获取TX锁的任何操作开始:


发出修改数据的语句(例如,插入,更新,删除,合并)

发出SELECT ... FOR UPDATE语句时

使用SET TRANSACTION语句或DBMS_TRANSACTION包显式启动事务时

发出COMMIT或ROLLBACK语句会明确结束当前事务。


本文将介绍如何使用以下语句和功能定义,管理和控制应用程序中的事务:


提交和回滚

保存点

自治交易

SET TRANSACTION语句

您可以在下面的事务处理和控制(doc)以及Oracle Live SQL和Oracle Dev Gym资源的链接中找到更多详细信息。


提交和回滚

回想一下事务的定义:“事务是Oracle数据库作为一个单元处理的一个或多个SQL语句的序列:要么执行所有语句,要么都不执行。” 当所有语句都“执行”时,这意味着您已将它们提交或保存到数据库中。


使用COMMIT语句保存所有更改,并使其对其他用户可见。请记住:在提交之前,没有人能够看到特定会话中所做的更改。提交后,每个有权访问受影响表的用户现在都可以看到表的新“状态”。


使用ROLLBACK语句撤消自上次提交以来(或自您在会话中启动第一个事务以来)的所有更改。


此LiveSQL教程(Oracle Dev Gym上的开发人员数据库课程的一部分)演示了事务管理的这些基本元素。


可是等等!如果您只想撤消会话中的某些更改,但保留其他更改,准备在将来的某个时间点提交,该怎么办?欢迎来到保存点世界。


保存点

保存点允许您回滚部分事务而不是整个事务。每个会话的活动保存点数量不受限制。


回滚到保存点时,标记在该保存点之后的任何保存点都将被删除。回滚的保存点不会被删除。简单的回滚或提交会擦除所有保存点。


保存点名称是未声明的标识符。在事务中重用保存点名称会将保存点从其旧位置移动到事务中的当前点,这意味着回滚到保存点仅影响事务的当前部分。


对于我们之间的递归程序员:如果在递归子程序中标记保存点,则SAVEPOINT语句的新实例在递归下降的每个级别运行,但是您只能回滚到最近标记的保存点。


以下是使用保存点的示例(从同一个LiveSQL教程中提取):

CREATE  TABLE玩具
(
   toy_id      INTEGER,
   toy_name    VARCHAR2(100),
   颜色      VARCHAR2(10)
)
/ 
宣布
   l_count    INTEGER ;
开始
   INSERT  INTO玩具(toy_id,toy_name,颜色)
        价值观(8,'Pink Rabbit','粉红色');
 
   SAVEPOINT after_six;
 
   INSERT  INTO玩具(toy_id,toy_name,颜色)
        价值观(9,'紫色忍者','紫色');
 
   SELECT  COUNT(*)
     INTO l_count
     来自玩具
    WHERE toy_id IN(8,9);
 
   DBMS_OUTPUT.put_line(l_count);
 
   ROLLBACK  TO  SAVEPOINT after_six;
 
   SELECT  COUNT(*)
     INTO l_count
     来自玩具
    WHERE toy_id IN(8,9);
 
   DBMS_OUTPUT.put_line(l_count);
 
   ROLLBACK ;
 
   SELECT  COUNT(*)
     INTO l_count
     来自玩具
    WHERE toy_id IN(8,9);
 
   DBMS_OUTPUT.put_line(l_count);
结束 ;
/
 
2
1
0

自治交易

默认情况下,执行COMMIT语句时,会保存会话中所有未保存的更改。当您回滚时,所有未保存的更改都将被删除。


但有时候,我们只想保存其中一个更改,而不保存其他更改。此方案的最典型用例是错误日志记录。我想将信息写入我的错误日志表并保存,但后来我需要回滚事务(毕竟,有一个错误)。


我可以使用保存点来执行此操作(请参阅上一节),但是当您调用可重用的日志记录程序时,很难一致且可靠。幸运的是,我可以简单地使我的错误记录过程成为一个自治事务。然后,我可以插入错误信息并提交该插入,而不会影响业务事务,随后将回滚该业务事务。


它很容易做到!


只需将此语句添加到过程或函数的声明部分......


PRAGMA AUTONOMOUS_TRANSACTION;

然后适用以下规则:


在关闭子程序并将控制权传递回调用块之前,必须提交或回滚在该子程序中进行的任何DML更改。

如果有任何未保存的更改,PL / SQL引擎将引发ORA-06519异常,如下所示:


创建 或 替换 功能没有返回 INTEGER

IS
   PRAGMA AUTONOMOUS_TRANSACTION;
开始
   UPDATE员工SET last_name = 'abc' ;
 
   返回 1 ;
结束 ;
/
 
开始
   DBMS_OUTPUT.put_line(无);
结束 ;
/
 
ORA- 06519:检测到并回滚了活动自治事务
ORA- 06512:在 “STEVEN.NOTHING”,第10行
ORA- 06512:在线路2
以下是在错误记录过程中使用此功能的示例:

CREATE  OR  REPLACE  PACKAGE  BODY error_mgr
IS 
   PROCEDURE log_error(app_info_in IN  VARCHAR2)
   IS 
      PRAGMA AUTONOMOUS_TRANSACTION;
      c_code    CONSTANT  INTEGER:= SQLCODE ;
   开始 
      INSERT  INTO error_log(created_on,
                             由...制作, 
                             错误代码, 
                             调用堆栈, 
                             errorstack, 
                             回溯, 
                             ERROR_INFO) 
           价值观(SYSTIMESTAMP,
                   用户,
                   c_code, 
                   DBMS_UTILITY.format_call_stack, 
                   DBMS_UTILITY.format_error_stack, 
                   DBMS_UTILITY.format_error_backtrace, 
                   app_info_in); 
 
      COMMIT ;
   结束 ;
结束 ;

此LiveSQL脚本包含完整(和非常基本)的错误记录包。


此LiveSQL脚本演示了自治事务编译指示的效果。


SET TRANSACTION语句

使用SET TRANSACTION语句将当前事务建立为只读或读/写,建立其隔离级别,将其分配给指定的回滚段,或为事务指定名称。


当您将事务设置为只读时,查询将返回事务开始时存在的数据,并且 您只能运行select语句。以下是使用此选项的示例,该选项来自Chris Saxon出色的LiveSQL模块:


集交易阅读 只 ;
 
从玩具中选择 * ;
 
更新玩具
设定     价格=价格+ 1 ;
 
宣布 
  pragma autonomous_transaction;
开始
  更新玩具套装价格= 99.00 ;
  提交 ;
结束 ;
/
 
从玩具中选择 * ;
提交 ;
从玩具中选择 * ;
以下是在LiveSQL中运行时的结果:



Oracle仅支持两个隔离级别:Read Committed和Serializable。


阅读已提交

这是Oracle数据库的默认模式。使用read committed,您具有语句级一致性。这意味着每个DML命令(选择,插入,更新或删除)都可以在开始之前查看保存的所有数据。其他会话启动后保存的任何更改都将被隐藏。


它使用多版本并发控制(MVCC)来实现。更新或删除行时,会将行的当前状态存储在undo中。因此,其他事务可以使用此撤消来查看过去存在的数据。


序列化

将事务设置为可序列化时,数据库就像您是数据库的唯一用户一样。其他交易所做的更改对您隐藏。Serializable还会阻止您更改由此错误导致的其他事务修改的行:


ORA-08177 can't serialize access for this transaction


换句话说,你是孤立的。


当事务多次访问相同的行时,请考虑使用serializable,并且您将有许多人同时运行事务。


标签:语句,事务,toy,更改,保存,回滚,SQL,101,PL
From: https://blog.51cto.com/u_16145034/6485334

相关文章

  • SQLite数据库的工作原理
    介绍数据库是构建软件系统的重要组成部分,用于有效地存储和读取数据。在这里,我们将使用早期版本的SQLite讨论数据库实现的一些体系结构细节。SQLite是一个小型数据库应用程序,用于数百万个软件和设备。SQLite是由D.RichardHipp于2000年8月发明的.SQLite是一个高性能,轻量级的关系数据......
  • MySQL数据库运维实录--通过MySQL Shell Dump/Load 实现数据库对象的逻辑备份与恢复
    [mysql@node01~]$mysqlshMySQLJS>\connectroot@node01:3306MySQLnode01:3306sslJS>util.dumpInstance('/home/mysql/backup')[mysql@node01~]$scp-rbackup/*node02:/home/mysql/backup/util.dumpInstance的关键特性1,多线程备份。并发线程数由thr......
  • sql 开窗函数
    开窗函数:在开窗函数出现之前存在着很多用SQL语句很难解决的问题,很多都要通过复杂的相关子查询或者存储过程来完成。为了解决这些问题,在2003年ISOSQL标准加入了开窗函数,开窗函数的使用使得这些经典的难题可以被轻松的解决。目前在MSSQLServer、Oracle、DB2等主流数据库中都......
  • mysql8.0创建新用户
     查看当前用户usemysql;selectcurrent_user();或者:selectUser,authentication_string,Hostfromuser;查看权限showgrantsfor'user'@'ip';或者showgrants;创建一个给新用户的数据库createdatabasetestDatabase;创建新用户同时配置给该用户testData......
  • 修复 Sqlite "database disk image is malformed"
    Sqlite是用于移动设备的轻量级数据库。Android编译遇到出错异常:databasediskimageismalformed 处理方法为通过对sqlite提供的修复命令建立脚本封装自动处理。修复方法来自网络搜索,年代久远,出处不可考,如找到出处,本文引用改为链接。 1#1.dumpSQL语句2def__d......
  • MySQL8.0设置外网访问
    1.登进MySQL之后mysql-uroot-p***2,输入以下语句,进入mysql库:usemysql3,更新域属性,'%'表示允许外部访问:updateusersethost='%'whereuser='root';4,执行以上语句之后再执行:FLUSHPRIVILEGES;5,再执行授权语句:GRANTALLPRIVILEGESON*.*TO'root'@'%......
  • MyBatis-Plus的BaseMapper与IService
    mybatis-plus提供两种包含预定义增删改查操作的接口:com.baomidou.mybatisplus.core.mapper.BaseMappercom.baomidou.mybatisplus.extension.service.IService刚开始有点疑惑为什么要设计俩个接口用来增删改查BaseMapper和IService的方法有很多类似的功能,但是方法名不同对比......
  • DataX在Windows上实现Mysql到Mysql同步数据以及配置多个job/多个表同步定时执行bat
    场景DataX-阿里开源离线同步工具在Windows上实现Sqlserver到Mysql全量同步和增量同步:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/130330353DataX-在Windows上实现postgresql同步数据到mysql:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/130......
  • 解决MySQL8.0报错:Unknown system variable 'validate_password_policy'
    解决MySQL8.0报错:Unknownsystemvariable'validate_password_policy'解决MySQL8.0报错:Unknownsystemvariable'validate_password_policy'一、问题描述1.通过yum安装好mysql8.0,通过生成的临时密码登录后操作mysql时会报如下错误:mysql>showdatabases;ERROR1820......
  • Mongodb - org.springframework.dao.DuplicateKeyException
    首先明确场景为mongodb,此异常在进行mongodb的插入操作时抛出,插入的主键已经存在。衍生场景,使用upsert时抛出,此处的包括了$set和$setOnInsert由于upsert非原子操作,如果在多线程环境下:线程A和线程B同时对数据库未存在的记录record1进行upsert,有可能会出现两个线程都判断为应该进行......