厘清概念-事务治理与锁控制-把握数据库并行性和完整性 (厘清概念还是理清概念)
散布式锁和事务是散布式系统中两个关键的概念,它们都用于处置散布式环境下的数据分歧性疑问。
一、概念
散布式锁
散布式锁是一种用于在散布式环境中控制对共享资源访问的锁。散布式锁可以防止多个进程或线程同时访问共享资源,从而防止数据抵触和资源竞争。
事务
事务是指一组操作要么所有口头,要么所有不口头,以保障数据的分歧性。事务理论用于处置多个数据源之间的操作,例如关于跨多个数据库的事务操作,须要保障在口头环节中的原子性、分歧性和耐久性。
区别
区别 |
散布式锁 |
事务 |
作用 |
控制对共享资源的访问 |
保障数据的分歧性 |
范畴 |
单个资源 |
多个资源 |
粒度 |
细粒度 |
粗粒度 |
成功 |
基于数据库、基于信息队列、基于共享内存等 |
基于ACID原理 |
优缺陷 |
好处:便捷易用、性能高;缺陷:不可保障数据分歧性 |
好处:保障数据分歧性;缺陷:成功复杂、性能低 |
经常使用场景 |
抢购、秒杀、数据同步等 |
银行转账、订单支付等 |
实质区别 |
散布式锁是针对资源访问的 |
事务是针对数据分歧性的 |
二、经常使用场景
散布式锁
散布式锁理论用于以下场景:
事务
事务理论用于以下场景:
三、实质区别
散布式锁可以防止多个进程或线程同时访问共享资源,从而防止数据抵触和资源竞争。事务可以保障数据在操作环节中的分歧性,即使在出现意外的状况下,也不会造成数据不分歧。
在实践运行中,可以依据详细的需求选用适合的打算。假设须要保障数据的分歧性,可以经常使用事务。假设只须要防止资源竞争,可以经常使用散布式锁。
四、锁与事务虚现
1、锁打算
散布式锁的成功方法有很多,经常出现的有以下几种:
Redisson是一个基于Redis的散布式框架。Redisson提供了丰盛的配置,包含散布式锁、散布式汇合、散布式队列等。
以下是经常使用Redisson成功散布式锁的示例:
@AutowiredprivateRedissonClientredissonClient;publicStringlock(){//失掉锁RLocklock=redissonClient.getLock("lock");booleanacquired=lock.tryLock(10,-1,TimeUnit.SECONDS);if(acquired){//失掉锁成功,口头业务逻辑return"失掉锁成功,口头业务逻辑...";}else{//失掉锁失败,重试return"失掉锁失败,重试...";}}publicStringunlock(){//监禁锁RLocklock=redissonClient.getLock("lock");lock.unlock();return"监禁锁成功...";}
另外,redisson允许锁续期。即在锁键值过时后义务还没口头成功,此时须要把锁键值的期间智能延伸。
Redisson提供了的续期机制,只需客户端加锁成功,就会启动一个WatchDog。可以看到源代码的成功leaseTime不设置为-1时开启监听。假设义务没成功就调用scheduleExpirationRenewal续期方法。
tryLock()方法用于尝试失掉散布式锁,该方法有三个参数:
waitTime参数示意客户端最多期待多长期间来失掉锁。假设在waitTime期间内没有失掉到锁,则会前往false。
leaseTime参数示意锁的过时期间。假设锁在leaseTime期间内没有被监禁,则会智能监禁。假设leaseTime设置为-1,则示意锁的过时期间由renew()方法来控制。这样,在业务逻辑口头环节中,可以活期调用lock.renew()方法来续期锁的过时期间。
tryLock()方法的前往值是一个Boolean值,示意能否成功失掉到锁。假设成功失掉到锁,则前往true。否则,前往false。
2、事务打算
以下是一些经常出现的散布式事务处置打算:
两阶段提交(2PC)
2PC是一种经典的散布式事务处置打算,它将散布式事务分为两个阶段:预备阶段和提交阶段。在预备阶段,协调者向一切介入者发送预提交恳求;假设一切介入者都赞同预提交,则进入提交阶段;否则,一切介入者都将回滚事务。2PC的好处是可以保障原子性、分歧性和隔离性,但是成功复杂度较高。
三阶段提交(3PC)
3PC是在2PC的基础上开展而来的一种改良打算,它引入了超机遇制和预提交照应等新个性。在3PC中,协调者会向一切介入者发送预提交恳求,并期待介入者的照应。假设一切介入者都赞同预提交,则进入预提交阶段;否则,进入回滚阶段。在正式提交阶段,假设一切介入者都赞同提交事务,则进入正式提交阶段;否则,一切介入者都将回滚事务。3PC的好处是可以更好地处置节点缺点等疑问,但是成功复杂度依然较高。
TCC(Try-Confirm-Cancel)
TCC是一种基于补救机制的散布式事务处置打算。它将散布式事务分为三个阶段:尝试阶段、确认阶段和敞开阶段。在尝试阶段,介入者尝试预留所需的资源,并口头一些审核和预备上班,以确保口头事务操作的前提条件满足;在确认阶段,假设一切介入者都满足,则一切介入者口头之前在Try阶段所预留的操作,并提交实践的数据耐久化。在敞开阶段,假设有任何一个介入者口头失败,则口头回滚操作,将系统形态复原到事务开局之前的形态。TCC的好处是可以防止阻塞状况的出现,但是成功复杂度较高。
Saga形式
Saga形式是一种基于事情驱动的散布式事务处置打算。它将散布式事务看作一系列的事情序列,每个事情都有一个惟一的ID和一个期间戳。在每个事情出现时,介入者会依据事情的内容口头相应的本地事务。假设某个介入者口头失败,则会记载该事情的形态为已失败,并期待其余介入者的照应。当一切的事情都被处置终了后,再口头最终的本地事务。Saga形式的好处是可以允许复杂的业务逻辑和意外状况处置,但是成功复杂度较高。
信息队列
信息队列可以用于异步地处置多个义务,并且可以保障义务的顺序口头。在散布式系统中经常使用信息队列来处置事务时,可以将事务拆分红多个小义务,并将这些义务颁布到信息队列中启动异步处置。当一切义务都成功后,再口头最终的本地事务。这种方式可以防止阻塞状况的出现,并且可以提高系统的可裁减性和容错才干。能保障事务的最终分歧性。
最大抵力通知(BestEffortDelivery)
这种处置打算经过异步通讯和信息重试来成功事务的最终分歧性。事务操作被封装为信息发送到指标系统,假设信息传递失败,系统会启动重试。
散布式事务两边件
Seata是一款阿里巴巴开源的散布式事务两边件,它提供了AT、TCC、SAGA和XA事务形式,为用户打造一站式的散布式处置打算。Seata的设计思绪是将一个散布式事务了解成全局事务,上方挂了若干个分支事务,而一个分支事务就是一个满足ACID的本地事务,因此咱们可以操作散布式事务像操作本地事务一样便捷。
数据库事务、存储过程、函数以及触发器之间的区别和联系
数据库事务、存储过程、函数以及触发器之间的区别和联系如下:
一、事务概念
事务(Transaction)是指构成单一逻辑工作单元的操作集合,要么完整地执行,要么完全不执行。
1、如果事务中有的操作没有成功完成,则事务中的所有操作都需要被回滚,回到事务执行前的状态(要么全执行,要么全都不执行)。
2、同时,该事务对数据库或者其他事务的执行无影响,所有的事务都好像在独立的运行。
二、事务举例
用一个常用的“A账户向B账户汇钱”的例子来说明如何通过数据库事务保证数据的准确性和完整性。熟悉关系型数据库事务的都知道从账户A到账户B需要6个操作,分别为:
1、从A账户中把余额读出来(500)。
2、对A账户做减法操作(500-100)。
3、把结果写回A账户中(400)。
4、从B账户中把余额读出来(500)。
5、对B账户做加法操作(500+100)。
6、把结果写回B账户中(600)。
三、事务特性
并非任意的对数据库的操作序列都是数据库事务,事务应该具有4个属性,分别为:原子性、一致性、隔离性和持久性。这四个属性通常称为ACID特性。
1、原子性(Atomicity):一个事务对数据库的所有操作,是一个不可分割的工作单元,这些操作要么全部被执行,要么都不执行;保证1-6所有过程要么都执行,要么都不执行。一旦在执行某一步骤的过程中发生问题,就需要执行回滚操作。假如执行到第5步的时候,B账户突然不可用(比如被注销),那么之前的所有操作都应该回滚到执行事务之前的状态。
2、一致性(Consistency):事务应确保数据库的状态从一个一致状态转为另一个一致状态,一致状态的含义是数据库中的数据应满足完整性约束;在转账之前,A和B的账户中共有500+500=1000元钱。在转账之后,A和B的账户中也应该共有400+600=1000元钱。
也就是说,数据的状态在执行该事务操作之后从一个状态改变到了另外一个状态,同时一致性还能保证账户余额不会变成负数等。
注:一致性与原子性是密切相关的,原子性的破坏可能导致数据库的不一致,数据的一致性问题并不都和原子性有关。
比如上面的例子,在第5步的时候,对B账户做加法时只加了50元。那么,该过程可以符合原子性,但是数据的一致性就出现了问题。因此,事务的原子性与一致性缺一不可。
3、隔离性(Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务的执行;在 A向B转账的整个过程中,只要事务还没有提交(commit),查询A账户和B账户的时候,两个账户里面的钱的数量都不会有变化。
如果在A给B转账的同时,有另外一个事务执行了C给B转账的操作,那么当两个事务都结束的时候,B账户里面的钱应该是A转给B的钱加上C转给B的钱再加上自己原有的钱。
4、持久性(Durability):一个事务一旦提交,它对数据库的修改应该永久保存在数据库中。
例如我们在数据库,用update语句更新某条记录时,会默认开启一个数据库事务,当我们执行(F8)这条语句后,再次查询这条记录,已经被更新,但没有提交事务,事务并没有对数据库产生影响。此时如果关闭查询窗口(出现故障),并未对数据库记录产生影响,只有将事务提交之后,这条记录才会真正并永久的更新。
四、事务并发
事务并发:一个数据库可能拥有多个访问客户端,这些客户端都可以并发方式访问数据库,数据库中的相同数据可能同时被多个事务访问,如果没有采取必要的隔离措施,就会导致各种并发问题,破坏数据的完整性。
并发问题归结:数据问题(脏读、幻读、不可重复读)、数据更新问题(更新丢失)。
一、存储过程的概念
①存储过程(Stored Procedure)是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中。
②存储过程是数据库中的一个重要对象,用户通过指定存储过程的名字并给出参数(可以有参数,也可以没有)来执行它。
③存储过程是流控制和SQL语句书写的过程,这个过程经编译和优化后存储在数据库服务器中。
④存储过程,可由应用程序通过一个调用来执行,而且允许用户声明变量。
⑤同时,存储过程可以接收和输出参数、返回执行存储过程的状态值,也可以嵌套调用。
二、存储过程的优点
①存储过程的使用大大增强了SQL语言的功能和灵活性。
存储过程可以用流控制语句编写,有很强的灵活性,可以完成复杂的判断和较复杂的运算。
②可保证数据的安全性和完整性。
通过存储过程可以使没有权限的用户在控制之下间接地存取数据库,从而保证数据的安全。
通过存储过程可以使相关的动作在一起发生,从而可以维护数据库的完整性,(就像事务的原子性:要么事务内的所有SQL语句全部执行成功,要么全部不成功)。
③在运行存储过程前,数据库已对其进行了语法和句法分析,并给出了优化执行方案。这种已经编译好的过程可极大地改善SQL语句的性能。由于执行SQL语句的大部分工作已经完成(因为已经提前经过编译),所以存储过程能以极快的速度执行。
④可以降低网络的通信量,客户端调用存储过程只需要传存储过程名和相关参数即可,与传输SQL语句相比自然数据量少了很多(在远程访问时体现出来)。
⑤存储过程只在创造时进行编译,以后每次执行存储过程都不需再重新编译,而一般SQL语句每执行一次就编译一次,所以使用存储过程可提高数据库执行速度。
⑥当对数据库进行复杂操作时(如对多个表进行Update,Insert,Query,Delete时),可将此复杂操作用存储过程封装起来,与数据库提供的事务处理结合一起使用。比如每一步对数据库的操作用一个事务来完成,把这些事务全都放在一个存储过程中。
⑦存储过程可以重复使用,可减少数据库开发人员的工作量。
⑧安全性高,可设定只有某些用户才具有对指定存储过程的使用权。
三、存储过程缺点
①调试麻烦:但是用PL/SQL Developer调试很方便,弥补这个缺点。
②移植问题:数据库端代码当然是与数据库相关的,但是如果是做工程型项目,基本不存在移植问题。
③重新编译问题:因为后端代码是运行前编译的,如果带有引用关系的对象发生改变时,受影响的存储过程、包将需要重新编译(不过也可以设置成运行时刻自动编译)。比如A存储过程调用B存储过程,使用B的返回值作为参数,如果B的参数或返回值发生改变时,会对调用她的A产生影响,此时存储过程就要重新编译,设置成运行时刻自动编译。
④维护比较困难:如果在一个程序系统中大量的使用存储过程,到程序交付使用的时候随着用户需求的增加会导致数据结构的变化,接着就是系统的相关问题了,最后如果用户想维护该系统可以说是很难很难、而且代价是空前的,维护起来更麻烦。
四、存储过程的种类
①系统存储过程:一般以“sp_”开头,用来进行系统的各项设定,获取配置信息,相关管理工作。
②本地存储过程:用户创建的存储过程,是由用户创建并完成某一特定功能的存储过程,事实上一般所说的存储过程就是指本地存储过程。
③临时存储过程:分为两种存储过程。
一是本地临时存储过程,以井字号(#)作为其名称的第一个字符,则该存储过程将成为一个存放在tempdb数据库中的本地临时存储过程,且只有创建它的用户才能执行它。
二是全局临时存储过程,以两个井字号(##)号开始,则该存储过程将成为一个存储在tempdb数据库中的全局临时存储过程,全局临时存储过程一旦创建,以后连接到服务器的任意用户都可以执行它,而且不需要特定的权限。
④远程存储过程:在SQL Server2005中,远程存储过程(Remote Stored Procedures)是位于远程服务器上的存储过程,通常可以使用分布式查询和EXECUTE命令(在SQL*Plus命令行窗口中)执行一个远程存储过程。
⑤扩展存储过程:扩展存储过程(Extended Stored Procedures)是用户可以使用外部程序语言编写的存储过程,而且扩展存储过程的名称通常以xp_开头。
五、存储过程的特性
1、存储过程与函数的区别
①返回值:函数只能返回一个变量,而存储过程可以返回多个,对于存储过程来说可以返回参数,如记录集,而函数只能返回值或者表对象。
②存储过程一般是作为一个独立的部分来执行(EXECUTE语句执行),而函数可以作为查询语句的一个部分来调用(SELECT调用),由于函数可以返回一个表对象,因此它可以在查询语句中位于FROM关键字的后面。SQL语句中不可用存储过程,而可以使用函数。
③存储过程实现的功能要复杂一点,而函数的实现的功能针对性比较强,比较单一。
2、存储过程与事务的区别
①存储位置:事务在程序中被调用,保存在调用以及实现它的代码中,存储过程可以在数据库客户端直接被调用,经编译后存储在数据库中。
②运行方式:事务在每次被调用的时候执行其中的SQL语句,存储过程预先经过编译,并不是每次被调用时都会执行一遍其中的SQL语句。
③事务有严格的一致性和原子性,使用的安全性高,存储过程则没有这些特性,在进行一些复杂的操作时,为了保证操作的准确性,可以在存储过程中调用事务,然后判断事务的执行结果是否成功来确保操作的准确性。
3、触发器
①概念及作用
触发器是一种特殊类型的存储过程,它不同于我们前面介绍过的存储过程。触发器主要是通过事件进行触发而被执行的,而存储过程可以通过存储过程名字而被直接调用。当对某一表进行诸如Update、Insert、Delete这些操作时,SQL Server就会自动执行触发器所定义的SQL语句,从而确保对数据的处理必须符合由这些SQL语句所定义的规则。
触发器的主要作用就是其能够实现由主键和外键所不能保证的复杂的参照完整性和数据的一致性。除此之外,触发器还有其它许多不同的功能:
(1)强化约束(Enforce restriction)触发器能够实现比CHECK语句更为复杂的约束。
(2)跟踪变化(Auditing changes)触发器可以侦测数据库内的操作,从而不允许数据库中未经许可的指定更新和变化。
(3)级联运行(Cascaded operation)触发器可以侦测数据库内的操作,并自动地级联影响整个数据库的各项内容。例如,某个表上的触发器中包含有对另外一个表的数据操作(如删除,更新,插入)而该操作又导致该表上触发器被触发。
(4)存储过程的调用(Stored procedure invocation)为了响应数据库更新,触发器可以调用一个或多个存储过程,甚至可以通过外部过程的调用而在DBMS(数据库管理系统)本身之外进行操作。
由此可见,触发器可以解决高级形式的业务规则或复杂行为限制,以及实现定制记录等一些方面的问题。例如,触发器能够找出某一表在数据修改前后状态发生的差异,并根据这种差异执行一定的处理,此外一个表的同一类(Insert、Update、Delete)的多个触发器能够对同一种数据操作采取多种不同的处理。
总体而言,触发器性能通常比较低,当运行触发器时,系统处理的大部分时间花费在参照其它表的这一处理上,因为这些表既不在内存中也不在数据库设备上,而删除表和插入表总是位于内存中,可见触发器所参照的其它表的位置决定了操作要花费的时间长短。
简述数据库的安全性和完整性有什么区别?
数据库的完整性的全名,关系数据库的参照完整性(Referential Integrity),一般是用在表示多个表之间关系时用的,而且经常使用。
数据库的安全性是指保护数据库以防止不合法的使用所造成的数据泄露、更改或破坏。
数据的完整性和安全性是数据库保护的两个不同方面。安全性是防止用户非法使用数据库。完整性则是防止合法用户使用数据库时向数据库中加入不合语义的数据。
免责声明:本文转载或采集自网络,版权归原作者所有。本网站刊发此文旨在传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及版权、内容等问题,请联系本网,我们将在第一时间删除。同时,本网站不对所刊发内容的准确性、真实性、完整性、及时性、原创性等进行保证,请读者仅作参考,并请自行核实相关内容。对于因使用或依赖本文内容所产生的任何直接或间接损失,本网站不承担任何责任。