首页 数据库 mysql教程 ORACLE 事务处理

ORACLE 事务处理

Jun 07, 2016 pm 03:24 PM
oracle 为什么 事务 事务处理 整理

ORACLE事务整理: 1、为什么要有事务的存在? 对数据库的访问是一个多用户且存在高并发的操作,如多用户在某一时间点上对同一条数据实行更新操作,导致数据严重混乱、不一致、破坏了数据的完整和安全性。 数据库事务管理这一应用横空出世,解决了多用户高并

ORACLE事务整理:

1、为什么要有事务的存在?

      对数据库的访问是一个多用户且存在高并发的操作,如多用户在某一时间点上对同一条数据实行更新操作,导致数据严重混乱、不一致、破坏了数据的完整和安全性。

      数据库事务管理这一应用横空出世,解决了多用户高并发下数据严重混乱的情况,很好的控制多用户高并发环境下所可能带来的数据混乱、不一致性,保证了数据完整性

      和安全性。此乃真是一计灵丹妙药(事务管理)。假设数据库不存在事务处理特性,导致后果主要有:

      1). 脏读:两个事务并发情况下,其中一个事务读取了另一个事务更新但未提交的记录,这时另外一个事务处于某种考虑回滚该更新操作。其中第一个数据读的数据就

              是数据库中不存在的数据,也就是脏数据,被称为脏读(oracle中不存在脏读)。

      2).幻读:一个事务,两个不同时间,读取的数据不同,被他人更新了。

      3).不可重复读:一个事务,T1有一个查询结果集,T2再查询,数据变多了,他人有插入。


     说白了,数据库事务处理就是为解决上面三个问题而存在的。操作数据库时加上事务特性处理,就不怕当前会话操作的数据,被另外一个会话所打搅。


2、什么是事务?

      事务是一条或多条SQL语句组成的逻辑执行块,这块中内容SQL要么全都执行成功,那么全执行失败。不存在部分SQL执行成功或失败。(之所以事务返回状态都是一致或

      成功或失败,是因为有事务隔离级别这么一说,见下文介绍)。事务使得执行数据库操作互不影响。


3、事务具备的特性?

     1). 原子性:一个事务要么全执行成功,要么全执行失败。比如,事务里面有100条执行SQL,要么100条SQL全部执行成功,如有一条执行失败,事务将其他执行成功SQL

                             回滚为之前状态。

     2).一致性:事务状态必须为一致的。比如,银行转账A账户给B账户装100¥,这是B账户+100¥同时A账户必须-100¥,从一个一致性状态转变为另外一个一致性状态。

     3).隔离性:事务执行互不影响。每个事务只能干预事己内部的操作,而无法干预别的事务操作。

     4).永久性:事务一旦提交,产生数据变化将是永久的。

4、控制事务命令(oracle中事务是隐式开始的,结束时需要显示结束commit,rollback):

     1、commit;  提交事务                  作用:--事务结束

     2、rollback; 回滚事务之前状态  作用:--事务结束

5、ORACLE事务隔离级别

     1). READ COMMITTED :读取提交事务;允许存在幻读、不重复读。不存在脏读。(脏读ORACLE中不存在)

     2).SERIALIZABLE:序列化级别;只能看见本事务开始前提交的数据,不存在幻读、不重复读、脏读。

     3).READ ONLY :只读事务;是序列化级别的子集,也只能看见本事务开始前提交的数据,但不允许在事务中进行DML语句

     ORACLE中事务级别只存在以上三种,其中READ COMMITTED 默认级别。 标准SQL事务级别为5种(想具体了解查询百度)。


6、设置事务隔离级别语法:

    SET transaction isolation level [read commited | serializable]    --设置读提交事务和序列化级别

    SET transaction isolation level read only;                                        --设置只读事务

7、事务处理演练(就以本机存在的classes表为例):


1、读提交事务和序列化事务级别进行事务处理

会话1:

SQL> select * from classes;                                                          
                                    CID CNAME
--------------------------------------- ----------
                                      1 0901
                                      2 0902
                                      3 0903

SQL> insert into classes values(4,'0904');
1 row inserted

--以上是会话1新增一条数据,但未提交事务。下面执行会话2查询该表操作

会话2

SQL> select * from classes;
                                    CID CNAME
--------------------------------------- ----------
                                      1 0901
                                      2 0902
                                      3 0903

--会话2查询结果集中,没有查到事务1新增未提交的数据,因为oracle默认的是读取提交后事务 READ COMMITED,也就是避免了脏读,ORACLE也就不存在脏读


会话1:提交事务

SQL> commit;
Commit complete

事务2再次执行查询语句:

SQL> select * from classes;
                                    CID CNAME
--------------------------------------- ----------
                                      1 0901
                                      2 0902
                                      3 0903
                                      4 0904


--会话2中包含了事务1提交的数据,发生了幻读


会话1:删除刚新增的一条记录并提交事务

SQL> delete from classes where cid=4;
1 row deleted

SQL> commit;
Commit complete

会话2:再次执行查询语句

SQL> select * from classes;
                                    CID CNAME
--------------------------------------- ----------
                                      1 0901
                                      2 0902
                                      3 0903

--会话2查询结果与之前查询结构不一致,未包含cid=4数据。发生了不可重复读。


会话2:为会话2设置事务,级别为:序列化级别

SQL> select * from classes;
                                    CID CNAME
--------------------------------------- ----------
                                      1 0901
                                      2 0902
                                      3 0903

SQL> SET transaction isolation level serializable;
Transaction set


会话1:新增一条数据并提交

SQL> insert into classes values(4,'0904');
1 row inserted

SQL> commit;
Commit complete

SQL> select * from classes;
                                    CID CNAME
--------------------------------------- ----------
                                      1 0901
                                      2 0902
                                      3 0903
                                      4 0904

会话2:进行再次执行查询语句

SQL> select * from classes;
                                    CID CNAME
--------------------------------------- ----------
                                      1 0901
                                      2 0902
                                      3 0903

--在会话2中执行查询语句,结果中未包含事务1新增数据,既看不到其他事务所做的修改,避免了幻读。对当前事务提交(结束),再次执行查询语句就可看到事务1新增的数据行。

会话2提交事务:

SQL> commit;
Commit complete

SQL> select * from classes;
                                    CID CNAME
--------------------------------------- ----------
                                      1 0901
                                      2 0902
                                      3 0903
                                      4 0904


会话2:再次设置事务级别为序列化级别

SQL> SET transaction isolation level serializable;
Transaction set


会话1:修改cid=4数据内容并提交

SQL> update classes set cname='0000' where cid=4;
1 row updated

SQL> commit;
Commit complete

SQL> select * from classes;
                                    CID CNAME
--------------------------------------- ----------
                                      1 0901
                                      2 0902
                                      3 0903
                                      4 0000       --此条记录已被永久修改

会话2:再次执行查询SQL

SQL> select * from classes;
                                    CID CNAME
--------------------------------------- ----------
                                      1 0901
                                      2 0902
                                      3 0903
                                      4 0904

--会话2执行查询语句,结果中看不到会话1中更改的数据,既看不到其他事务所修改的数据,避免了不可重复读。


————————————————————————————————————————————————————————————————————————————

使用只读级别进行事务处理:

会话2:将事务2设置为只读级别

SQL> SET transaction read only ;
Transaction set

SQL> select * from classes;
                                    CID CNAME
--------------------------------------- ----------
                                      1 0901
                                      2 0902
                                      3 0903

会话1:新增一条数据并提交

SQL> insert into classes values(4,'0904');
1 row inserted

SQL> commit;
Commit complete

会话2:执行查询SQL结果

SQL> select * from classes;
                                    CID CNAME
--------------------------------------- ----------
                                      1 0901
                                      2 0902
                                      3 0903

--会话2中执行查询语句,结果中未包含会话1新增的数据,既看不到其他事务所做的修改,避免了幻读。对当前事务进行提交,再将事务级别设置为只读事务

SQL> commit;
Commit complete

SQL> SET transaction read only ;
Transaction set


会话1:更新一条记录并提交

SQL> update classes set cname='0000' where cid=4;
1 row updated

SQL> commit;
Commit complete

SQL> select * from classes;
                                    CID CNAME
--------------------------------------- ----------
                                      1 0901
                                      2 0902
                                      3 0903
                                      4 0000

会话2:执行查询语句

SQL> select * from classes;
                                    CID CNAME
--------------------------------------- ----------
                                      1 0901
                                      2 0902
                                      3 0903
                                      4 0904

--会话2中查询结果看不到会话1更改的数据,既看不到其他事务所做的修改。避免了不可重复读。对当前事务进行提交。再将事务级别设置为可读取级别


事务2:设置为可读取级别,执行修改数据操作。

SQL> select * from classes;
                                    CID CNAME
--------------------------------------- ----------
                                      1 0901
                                      2 0902
                                      3 0903
                                      4 0000

SQL> SET transaction read only ;
Transaction set

SQL> update classes set cname='1111' where cid=4;
update classes set cname='1111' where cid=4
ORA-01456: 不能在 READ ONLY 事务处理中执行插入/删除/更新操作

--ORACLE可读事务只能查询,不能做修改才做所以报错。


本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它们
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

oracle怎么循环创建游标 oracle怎么循环创建游标 Apr 12, 2025 am 06:18 AM

Oracle 中,FOR LOOP 循环可动态创建游标, 步骤为:1. 定义游标类型;2. 创建循环;3. 动态创建游标;4. 执行游标;5. 关闭游标。示例:可循环创建游标,显示前 10 名员工姓名和工资。

oracle动态sql怎么创建 oracle动态sql怎么创建 Apr 12, 2025 am 06:06 AM

可以通过使用 Oracle 的动态 SQL 来根据运行时输入创建和执行 SQL 语句。步骤包括:准备一个空字符串变量来存储动态生成的 SQL 语句。使用 EXECUTE IMMEDIATE 或 PREPARE 语句编译和执行动态 SQL 语句。使用 bind 变量传递用户输入或其他动态值给动态 SQL。使用 EXECUTE IMMEDIATE 或 EXECUTE 执行动态 SQL 语句。

oracle awr报告怎么看 oracle awr报告怎么看 Apr 11, 2025 pm 09:45 PM

AWR 报告是显示数据库性能和活动快照的报告,解读步骤包括:识别活动快照的日期和时间。查看活动、资源消耗的概览。分析会话活动,找出会话类型、资源消耗和等待事件。查找潜在性能瓶颈,如缓慢的 SQL 语句、资源争用和 I/O 问题。查看等待事件,识别并解决它们以提高性能。分析闩锁和内存使用模式,以识别导致性能问题的内存问题。

oracle游标关闭怎么解决 oracle游标关闭怎么解决 Apr 11, 2025 pm 10:18 PM

解决 Oracle 游标关闭问题的方法包括:使用 CLOSE 语句显式关闭游标。在 FOR UPDATE 子句中声明游标,使其在作用域结束后自动关闭。在 USING 子句中声明游标,使其在关联的 PL/SQL 变量关闭时自动关闭。使用异常处理确保在任何异常情况下关闭游标。使用连接池自动关闭游标。禁用自动提交,延迟游标关闭。

oracle怎么打开数据库 oracle怎么打开数据库 Apr 11, 2025 pm 10:51 PM

打开 Oracle 数据库的步骤如下:打开 Oracle 数据库客户端连接到数据库服务器:connect username/password@servername使用 SQLPLUS 命令打开数据库:SQLPLUS

oracle怎么使用触发器 oracle怎么使用触发器 Apr 11, 2025 pm 11:57 PM

Oracle 中的触发器是用于在特定事件(插入、更新或删除)触发后自动执行操作的存储过程。它们用于各种场景,包括数据验证、审核和数据维护。创建触发器时,需要指定触发器名称、关联表、触发事件和触发时间。有两种类型的触发器:BEFORE 触发器在操作之前触发,而 AFTER 触发器在操作之后触发。例如,BEFORE INSERT 触发器可确保插入行的年龄列不为负。

oracle中乱码怎么解决 oracle中乱码怎么解决 Apr 11, 2025 pm 10:09 PM

Oracle 乱码问题可以通过以下步骤解决:检查数据库字符集以确保与数据相匹配。设置客户端字符集以与数据库相匹配。转换数据或修改列字符集以匹配数据库字符集。使用 Unicode 字符集,并避免多字节字符集。检查数据库和客户端的语言设置是否正确。

oracle打不开怎么办 oracle打不开怎么办 Apr 11, 2025 pm 10:06 PM

Oracle 打不开的解决办法包括:1. 启动数据库服务;2. 启动监听器;3. 检查端口冲突;4. 正确设置环境变量;5. 确保防火墙或防病毒软件未阻止连接;6. 检查服务器是否已关闭;7. 使用 RMAN 恢复损坏的文件;8. 检查 TNS 服务名称是否正确;9. 检查网络连接;10. 重新安装 Oracle 软件。

See all articles