您的位置:首页 > 数据库 > MySQL

Mysql事务

2018-03-07 09:52 190 查看
所谓的事务就是保证以上的多个步骤在同一个环境中执行,只要其中一个失败,事务就会撤销之前的操作,回滚到之前的状态,如果都执行成功,那么事务就认为成功了。这就是事务的作用。

对事务有了初步理解后,进一步了解事务的官方概念,事务是DBMS的执行单位。它由有限个数据库操作语句组成。但不是任意的数据库操作序列都能成为事务。一般来说,事务是必须满足4个条件(ACID

原子性(Autmic):一个原子事务要么完整执行,要么干脆不执行。也就是说,工作单元中的每项任务都必须正确执行,如果有任一任务执行失败,则整个事务就会被终止并且此前对数据所作的任何修改都将被撤销。如果所有任务都被成功执行,事务就会被提交,那么对数据所作的修改将会是永久性的

一致性(Consistency):一致性代表了底层数据存储的完整性。 它是由事务系统和应用开发人员共同来保证。事务系统通过保证事务的原子性,隔离性和持久性来满足这一要求; 应用开发人员则需要保证数据库有适当的约束(主键,引用完整性等),并且工作单元中所实现的业务逻辑不会导致数据的不一致(数据预期所表达的现实业务情况不相一致)。例如,在刚才的AB转账过程中,从A账户中扣除的金额必须与B账户中存入的金额相等。

隔离性(Isolation):隔离性是指事务必须在不干扰其他事务的前提下独立执行,也就是说,在事务执行完毕之前,其所访问的数据不能受系统其他部分的影响。

持久性(Durability):持久性指明当系统或介质发生故障时,确保已提交事务的更新数据不能丢失,也就意味着一旦事务提交,DBMS保证它对数据库中数据的改变应该是永久性的,耐得住任何系统故障,持久性可以通过数据库备份和恢复来保证。



悲观锁和乐观锁的概念

悲观锁:假设会发生并发冲突,回避一切可能违反数据完整性的操作。

乐观锁:假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性,注意乐观锁并不能解决脏读的问题。

在一般情况下,悲观锁依靠数据库的锁机制实现,以保证操作最大程度的排他性和独占性,因而会导致数据库性能的大量开销和并发性很低,特别是对长事务而言,这种开销往往过于巨大而无法承受。为了解决这样的问题,乐观锁机制便出现了。乐观锁,大多情况下是基于数据版本( Version )记录机制实现。何谓数据版本?即为数据增加一个版本标识,在基于数据库表的版本解决方案中,一般是通过为数据库表增加一个 “version” 字段来实现。读取出数据时,将此版本号一同读出,之后更新时,对此版本号加一。此时,将提交数据的版本数据与数据库表对应记录的当前版本信息进行比对,如果提交的数据版本号大于数据库表当前版本号,则给予更新,否则认为是过期数据。

mysql中的共享锁与排他锁

在mysql中,为了保证数据一致性和防止数据处理冲突,引入了加锁和解锁的技术,这样可以使数据库中特定的数据在使用时不让其他用户(进程或事务)操作而为该数据加锁,直到该数据被处理完成后再进行解锁。根据使用目的不同把锁分为共享锁定(也称为读取锁定)和排他锁定(写入锁定)。

共享锁定:将对象数据变为只读形式的锁定,这样就允许多方同时读取一个数据,此时数据将无法修改。

排他锁定:在对数据进行insert/update/delete时进行锁定,在此时其他用户(进程或事务)一律不能读取数据,从而也保证数据完整性。

以上两种锁都属于悲观锁的应用,还有一点,根据锁定粒度的不同,可分为行锁定(共享锁和排他锁使用应用的就是行锁定),表锁定,数据库锁定,可见粒度的不同将影响用户(进程或事务)对数据操作的并发性,目前mysql支持行锁定和表锁定。

事务处理分离水平

的出现更多的是为了在多个用户(进程或事务)同时执行更新操作时保证数据的完整性和一致性,但随之而来的问题是当数据的锁定时间越长,数据同时运行性也会随之降低。也就意味着当一个用户(进程或事务)对数据保存锁定时,其他用户(进程或事务)只能等待锁定解锁,这样也就导致并发访问该数据的同时性较低。所以在多用户(进程或事务)对数据进行更新或者访问的同时如何保证数据的完整性和一致性,这样的情况下需要有一个相对折中的妥协,因为并不是频繁锁定数据或者极致提供同时运行性就是合理的,为了描述这个问题数据库中引入分离水平(有些地方称为隔离级别)的概念来确定事务处理之间的相互影响程度。其规则描述:分离水平越高,数据的完整性也就越高,但同时运行性下降,相反如果分离水平越低数据完整性越低,同时运行性也就提高了。

四种分离水平(隔离级别)

READ_UNCOMMITTED:这是事务最低的分离水平(隔离级别),它充许别外一个事务可以看到这个事务未提交的数据,会出现脏读、不可重复读、幻读 (分离水平最低,并发性能高)

READ_COMMITTED:保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据。可以避免脏读,但会出现不可重复读、幻读问题(锁定正在读取的行,mysql默认隔离级别)

REPEATABLE_READ:可以防止脏读、不可重复读,但会出幻读(锁定所读取的所有行)

SERIALIZABLE:这是花费最高代价但是最可靠的事务分离水平(隔离级别),事务被处理为顺序执行。保证所有的情况不会发生(锁表,并发性及其低)

读未提交、不可重复读,幻读

读未提交,也称脏读,脏读发生在一个事务读取了另一个事务改写但尚未提交的数据时。如果改写在稍后被回滚了,那么第一个事务获取的数据就是无效的。

不可重复读:不可重复读发生在一个事务执行相同的查询两次或两次以上,但是每次都得到不同的数据时。这通常是因为另一个并发事务在两次查询期间进行了更新。请注意,不可重复读重点是修改数据导致的(修改数据时排他读);

幻读:幻读与不可重复读类似。它发生在一个事务(T1)读取了几行数据,接着另一个并发事务(T2)插入了一些数据时。在随后的查询中,第一个事务(T1)就会发现多了一些原本不存在的记录。请注意,幻读重点是插入或者删除数据导致的(对满足条件的数据行集进行锁定),
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息