热门标签 | HotTags
当前位置:  开发笔记 > 数据库 > 正文

事务处理和并发控制

什么是事务是一种机制、一个操作序列、它包含了一组数据库操作命令,并且所有的命令作为一个整体,一起向系统提交或撤销操作请求。由一个或多个完成一种相关行为的SQL语句组成。是一个不可分割的工作逻辑单元。在事务处理中,一旦某个操作发生异常,则整个

什么是事务 是一种机制、一个操作序列、它包含了一组数据库操作命令,并且所有的命令作为一个整体,一起向系统提交或撤销操作请求。由一个或多个完成一种相关行为的SQL语句组成。是一个不可分割的工作逻辑单元。 在事务处理中,一旦某个操作发生异常,则整个

什么是事务

是一种机制、一个操作序列、它包含了一组数据库操作命令,并且所有的命令作为一个整体,一起向系统提交或撤销操作请求。由一个或多个完成一种相关行为的SQL语句组成。是一个不可分割的工作逻辑单元。

在事务处理中,一旦某个操作发生异常,则整个事务都会重新开始,数据库也会返回到事务开始之前的状态,在事务中对数据库所做的一切操作都会取消。事务要是成功的话,事务中所有的操作都会执行。

事务控制语句:COMMIT:提交事务,即把事务中对数据库的修改进行永久保存。

ROLLBACK:回滚事务,即取消对数据库所做的任何修改。

事务的特性:1、原子性(Atomicity):事务是一个完整的操作。事务的各步操作是不可分的(原子的),要么都执行,要么都不执行。2、一致性(Consistency):在事务操作前后,数据必须处于一致状态。3、隔离性(Isolation):对数据进行修改的所有并发事务彼此隔离的,这表明事务必须是独立的,他不应该以任何方式依赖于或影响其他事务。4、持久性(Durability):事务完成后,他对数据的修改被永久保持。

示例:ACCOUNT_BALANCE表示用户余额ACCOUTN_ID表示用户id。

BEGIN
 UPDATE ACCOUNT SETACCOUNT_BALANCE=ACCOUNT_BALANCE-4000;
       WHERE ACCOUNT_ID=’1001’;
 UPDATE ACCOUNT SETACCOUNT_BALANCE=ACCOUNT_BALANCE+4000;
       WHERE ACCOUNT_ID=’1002’;
COMMIT;
EXCEPTION
       WHERE OTHERS THEN ROLLBACK;
DBMS_OUTPUT.PUT_LINE(‘转账异常,停止转账!’);
END;

事务一致性要求:在事务处理开始之前,数据库的所有数据都满足业务规则约束;当事务处理结束后,数据库中的所有数据仍然满足业务规则约束。

示例:

DECLARE
       account_a ACCOUNT.ACCOUNT_BALANCE%TYPE;
       account_b ACCOUNT.ACCOUNT_BALANCE%TYPE;
BEGIN
       SELECT ACCOUNT_BALANCE INTO account_aFROM ACCOUNT WHERE ACCOUNT_ID=’1001’;
       SELECT ACCOUNT_BALANCE INTO account_bFROM ACCOUNT WHERE ACCOUNT_ID=’1002’;
       dbms_output.put_line(‘转账前A金额:’);
       dbms_output.put_line(account_a);
       dbms_output.put_line(‘转账前B的金额:’);
       dbms_output.put_line(account_b);
       dbms_output.put_line(‘转账前总金额:’);
       dbms_output.put_line(account_a+account_b);
       UPDATE ACCOUNT SETACCOUNT_BALANCE=ACCOUNT_BALANCE-2000
WHERE ACCOUNT_ID=’1001’;
       UPDATE ACCOUNT SETACCOUNT_BALANCE=ACCOUNT_BALANCE+2000
WHERE ACCOUNT_ID=’1002’;
       COMMIT;
       dbms_output.put_line(‘成功转账!’);
       SELECT ACCOUNT_BALANCE INTO account_aFROM ACCOUNT WHERE ACCOUNT_ID=’1001’;
       SELECT ACCOUNT_BALANCE INTO account_bFROM ACCOUNT WHERE ACCOUNT_ID=’1002’;
       dbms_output.put_line(‘转账后A金额:’);
       dbms_output.put_line(account_a);
       dbms_output.put_line(‘转账后B金额:’);
       dbms_output.put_line(account_b);
       dbms_output.put_line(‘转账后总金额:’);
       dbms_output.put_line(account_a+account_b);
       EXCEPTION WHEN OTHERS THEN ROLLBACK;
       dbms_output.put_line(‘转账异常,停止转账!’);
       SELECT ACCOUNT_BALANCE INTO account_aFROM ACCOUNT WHERE ACCOUNT_ID=’1001’;
       SELECT ACCOUNT_BALANCE INTO account_bFROM ACCOUNT WHERE ACCOUNT_ID=’1002’;
       dbms_output.put_line(‘停止转账后A金额:’);
       dbms_output.put_line(account_a);
       dbms_output.put_line(‘停止转账后B金额:’);
       dbms_output.put_line(account_b);
       dbms_output.put_line(‘停止转账后总金额:’);
       dbms_output.put_line(account_a+account_b);
END;

读取异常的情况:1、脏读:一个事务读取了另一个事务未提交的数据。2、不可重复读,一个事务在次读取之前曾读取过的数据时,发现该数据已经被另一个已提交的事务修改。3、幻读:一个事务根据相同的查询条件,重新执行查询,返回的记录中包含与前一次执行查询返回的记录不同的行。

ANSISQL-92标准中定义的事务隔离级别:

ReadUncommitted最低等的事务隔离,它仅仅保证了读取过程中不会读取到非法数据,

ReadCommitted,此级别的书屋隔离保证了一个事务不会读到另一个并行事务已修改但未提交的数据,也就是说此级别的事务级别避免了“脏读”。

RepeatableRead,此级别的事务隔离避免了“脏读”和“不可重复读”异常现象的出现。这也意味着,一个事务不可能更新已经由另一个事务读取但未提交的数据。可能引发幻读。

Serializable,最高等级的隔离级别,提供了最高等级的隔离机制,三种异常情况都能避免。

隔离等级

脏读

不可重复读

幻读

Read Uncommitted

可能

可能

可能

Read Committde

不可能

可能

可能

Repeatable Read

不可能

不可能

可能

Serializable

不可能

不可能

不可能

Oracle的事务隔离级别:1、ReadCommitted。2、Serializable;

3、Read Only是Serialzable的子集,但事务中不能有任何修改数据库中数据的语句(DML),以及修改数据库结构的语句(DDL);

Oracle中不需要专门的语句来开始事务。隐含的,事务会在修改数据的第一条鱼具处开始。

结束事务:1、COMMIT语句显式终止一个事务。当执行COMMIT语句时,在事务中对数据的修改都会保存到数据库中。2、ROLLBACK语句回滚事务,当执行ROLLBACK语句时,将取消在事务中对数据库所做的任何修改。3、执行一条DDL语句,如果DDL语句前已经有DML语句,则Oracle会把前面的DML语句作为一个事务提交。4、用户断开与Oracle的链接,用户当前事务将被自动提交。5、用户进程意外被终止,这时用户当前的事务被回滚。

事务控制语句:1、COMMIT:提交事务,即把事务中对数据库的修改进行永久保存。2、ROLLBACK:回滚事务,即取消对数据库所做的任何修改。3、SAVEPOINT:在事务中创建存储点。4、ROLLBACKTO:将事务回滚到存储点。5、SET TRANSACTION:设置事务的属性。

SAVEPOINT:在事务中创建存储点。语法:SAVEPOINT[SavePoint_Name];

ROLLBACKTO:将事务回滚到存储点。语法:ROLLBACK TO[SavePoint_Name];

示例:

BEGIN
	UPDATE ACCOUNT SETACCOUNT_BALANCE=ACCOUNT_BALANCE+2000 WHEN ACCOUNT_ID=’1001’;
	SAVEPOINT Add_Account_A;
	UPDATE ACCOUNT SET ACCOUNT_BALANCE= ACCOUNT_BALANCE-6000 WHEN ACCOUNT_ID=’1001’;
	UPDATE ACCOUNT SETACCOUNT_BALANCE=ACCOUNT_BALANCE+6000 WHEN ACCOUNT_ID=’1002’;
	COMMIT;
	EXCEPTION
	     WHENOTHERS THEN dbms_output.put_line(‘转账异常!’);
	     ROLLBACK TO Add_Account_A;
END;

SETTRANSACTION语句必须是事务的第一条语句,他可以指定事务的隔离级别、规定回滚事务时所使用的存储空间、对事务命名。

设置访问级别的方法:SET TRANSACTION READ ONLY; SET TRANSACTION ISOLATION LEVEL READCOMMITED; SET TRANASCTION ISOLATION LEVEL SERIALIZABLE;

并发控制:指用正确的方式实现事务的并发操作,避免造成数据的不一致。

并发控制带来的问题:1、丢失更新,一个事务修改某行数据时,另一个事务同时修改了该行数据,使第一个事务对数据的修改丢失。2、脏读。3、不可重复读。4、幻读。

锁的基本概念:锁,用来共享资源控制并发访问的一种机制。锁由Oracle自动管理,锁持续的时间等于被提交事务处理的时间。

锁的类型:1、共享锁(使用共享锁的数据对象可以被其他事务读取,但不能修改),也称s锁。2、排他锁,也称x锁。按锁保护的内容分类:DML锁,用来保护数据的完整性和一致性;DDL锁,用来保护数据对象结构定义;内部锁和闩,用来保护数据库内部数据结构。

死锁:两个事务(会话)都进入了彼此等候对方锁定的资源时的一种停止状态。

解决死锁:“牺牲”一个会话,回滚一个会话事务,使另一个会话的事务继续执行。

在发生死锁时Oracle数据库会在服务器上创建一个跟踪文件记录死锁。

注意:不要在开发过程中人为的提供条件使Oracle产生死锁。

阻塞:如果一个会话持有某个资源的锁,而另一个会话在请求这个资源就造成了阻塞。

锁机制问题:1、悲观锁,是指在读取数据后马上锁定相关资源。语法:SELECT…………FORUPDATE[OF column_list][WAIT n|NOWAIT] OF子句用于指定即将更新的列,即锁定行上的特定列;WAIT子句指定等待其他用户释放的秒数,防止无限期的等待,NOWAIT表示不等待。

示例:

SELECT * FROM ACCOUNT WHEREACCOUNT .ID=’1001’ FOR UPDATE;
UPDATE ACCOUNT SETBALANCE=BALANCE-500 WHERE ID=’1001’;

乐观锁:把所有锁定都延迟到即将执行更新之前。

语法:

UPDATE Table_Name SETColumn_Name1=NewValue1,Column_Name2=NewValue2……
WHERE Column_Name1=OldValue1 ANDColumn_Name2=OldValue2……

示例:

DECLARE 
 account_a ACCOUNT.BALANCE%TYPE;
BEGIN
       SELECT balance INTO account_a FROMACCOUNT WHERE ID=’1001’;
       UPDATE ACCOUNT SET balance=balance-500WHERE ID=’1001’ AND BALANCE=account_a;
END;

锁的分类:DML锁用于确保一次只有一个用户能修改一行,而且正在处理一个表时,别人也不能删除这张表。

DML锁主要包括TX锁、TM锁,其中TX锁是事务锁或行级锁,TM锁成为表级锁。

TX锁:事务发起第一个修改数据的语句时会自动得到TX锁,而且会一直持有这个锁,知道事务提交或回滚。TX锁用作一种排队机制,使得其他会话可以等待这个事务执行。事务中修改或通过悲观锁定选择的每一行都会指向该事务的一个相关TX锁。

TM锁:用于确保在修改表的内容是,表的结构不会改变当一个会话开始更新一个表时,会自动获得这个表的TM锁,这样能够防止,另外一个在该表上执行DROP或者ALTER语句删除该表或更改该表的结构。

DDL锁:用来保护数据对象结构定义,DDL操作会自动为数据库对象加DDL锁。

注意:Oracle中,DDL语句包装在隐式提交(回滚)中来执行操作。


推荐阅读
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • PHP设置MySQL字符集的方法及使用mysqli_set_charset函数
    本文介绍了PHP设置MySQL字符集的方法,详细介绍了使用mysqli_set_charset函数来规定与数据库服务器进行数据传送时要使用的字符集。通过示例代码演示了如何设置默认客户端字符集。 ... [详细]
  • Centos7.6安装Gitlab教程及注意事项
    本文介绍了在Centos7.6系统下安装Gitlab的详细教程,并提供了一些注意事项。教程包括查看系统版本、安装必要的软件包、配置防火墙等步骤。同时,还强调了使用阿里云服务器时的特殊配置需求,以及建议至少4GB的可用RAM来运行GitLab。 ... [详细]
  • 本文介绍了在Hibernate配置lazy=false时无法加载数据的问题,通过采用OpenSessionInView模式和修改数据库服务器版本解决了该问题。详细描述了问题的出现和解决过程,包括运行环境和数据库的配置信息。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • 本文介绍了如何找到并终止在8080端口上运行的进程的方法,通过使用终端命令lsof -i :8080可以获取在该端口上运行的所有进程的输出,并使用kill命令终止指定进程的运行。 ... [详细]
  • 本文介绍了adg架构设置在企业数据治理中的应用。随着信息技术的发展,企业IT系统的快速发展使得数据成为企业业务增长的新动力,但同时也带来了数据冗余、数据难发现、效率低下、资源消耗等问题。本文讨论了企业面临的几类尖锐问题,并提出了解决方案,包括确保库表结构与系统测试版本一致、避免数据冗余、快速定位问题等。此外,本文还探讨了adg架构在大版本升级、上云服务和微服务治理方面的应用。通过本文的介绍,读者可以了解到adg架构设置的重要性及其在企业数据治理中的应用。 ... [详细]
  • 禁止程序接收鼠标事件的工具_VNC Viewer for Mac(远程桌面工具)免费版
    VNCViewerforMac是一款运行在Mac平台上的远程桌面工具,vncviewermac版可以帮助您使用Mac的键盘和鼠标来控制远程计算机,操作简 ... [详细]
  • 本文详细介绍了云服务器API接口的概念和作用,以及如何使用API接口管理云上资源和开发应用程序。通过创建实例API、调整实例配置API、关闭实例API和退还实例API等功能,可以实现云服务器的创建、配置修改和销毁等操作。对于想要学习云服务器API接口的人来说,本文提供了详细的入门指南和使用方法。如果想进一步了解相关知识或阅读更多相关文章,请关注编程笔记行业资讯频道。 ... [详细]
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 如何基于ggplot2构建相关系数矩阵热图以及一个友情故事
    本文介绍了如何在rstudio中安装ggplot2,并使用ggplot2构建相关系数矩阵热图。同时,通过一个友情故事,讲述了真爱难觅的故事背后的数据量化和皮尔逊相关系数的概念。故事中的小伙伴们在本科时参加各种考试,其中有些沉迷网络游戏,有些热爱体育,通过他们的故事,展示了不同兴趣和特长对学习和成绩的影响。 ... [详细]
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 本文介绍了使用PHP实现断点续传乱序合并文件的方法和源码。由于网络原因,文件需要分割成多个部分发送,因此无法按顺序接收。文章中提供了merge2.php的源码,通过使用shuffle函数打乱文件读取顺序,实现了乱序合并文件的功能。同时,还介绍了filesize、glob、unlink、fopen等相关函数的使用。阅读本文可以了解如何使用PHP实现断点续传乱序合并文件的具体步骤。 ... [详细]
author-avatar
乐土网6868
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有