数据库事务是数据库管理系统执行过程当中的一个逻辑单位,由一个有限的数据库操做序列构成。但不是任意的数据库操做序列都能成为事务 对mysql常见的引擎有:MyISAM和InnoDB,MyISAM是默认高速的引擎并不支持事务功能,InnoDB支持行锁定和事务处理,速度比MyISAM稍慢。 它的存在包含有如下两个目的: 1.为数据库操做序列提供了一个从失败中恢复到正常状态的方法,同时提供了数据库即便在异常状态下仍能保持一致性的方法。 2.当多个应用程序在并发访问数据库时,能够在这些应用程序之间提供一个隔离方法,以防止彼此的操做互相干扰。
READ_UNCOMMITTED:这是事务最低的隔离级别,它充许别外一个事务能够看到这个事务未提交的数据,会出现脏读、不可重复读、幻读 (隔离级别最低,并发性能高)mysql
READ_COMMITTED:保证一个事务修改的数据提交后才能被另一个事务读取。另一个事务不能读取该事务未提交的数据。能够避免脏读,但会出现不可重复读、幻读问题(锁定正在读取的行,mysql默认隔离级别)sql
REPEATABLE_READ:能够防止脏读、不可重复读,但会出幻读(锁定所读取的全部行)数据库
SERIALIZABLE:这是花费最高代价可是最可靠的事务隔离级别,事务被处理为顺序执行。保证全部的状况不会发生(锁表,并发性及其低)并发
隔离级别 | 读未提交 | 不可重复读 | 幻读 |
---|---|---|---|
READ UNCOMMITTED | 会 | 会 | 会 |
READ COMMITTED | 不 | 会 | 会 |
REPEATABLE READ | 不 | 不 | 会 |
SERIALIZABLE | 不 | 不 | 不 |
读未提交:事务T2能读取事务T1未提交的数据,当事务T1执行回滚时,T2读取的数据就无效性能
不可重复读:事务T2读取事务T1未开启时和T1提交后的数据不一致(主要是数据更新致使不一致)code
幻读:事务T2读取事务T1未开启时和T1提交后的数据不一致(此时已锁定T2读取行,主要是插入和删除数据致使不一致)对象
// 设置当前链接的事务隔离级别
SET SESSION TRANSACTION ISOLATION LEVEL 事务隔离级别;
//设置所有链接(包括新链接)的事务隔离级别
SET GLOBAL TRANSACTION ISOLATION LEVEL 事务隔离级别;索引
悲观锁:假设会发生并发冲突,回避一切可能违反数据完整性的操做。进程
乐观锁:假设不会发生并发冲突,只在提交操做时检查是否违反数据完整性,注意乐观锁并不能解决脏读的问题。事务
在通常状况下,悲观锁依靠数据库的锁机制实现,以保证操做最大程度的排他性和独占性,于是会致使数据库性能的大量开销和并发性很低,特别是对长事务而言,这种开销每每过于巨大而没法承受。为了解决这样的问题,乐观锁机制便出现了。乐观锁,大多状况下是基于数据版本( Version )记录机制实现。何谓数据版本?即为数据增长一个版本标识,在基于数据库表的版本解决方案中,通常是经过为数据库表增长一个 “version” 字段来实现。读取出数据时,将此版本号一同读出,以后更新时,对此版本号加一。此时,将提交数据的版本数据与数据库表对应记录的当前版本信息进行比对,若是提交的数据版本号大于数据库表当前版本号,则给予更新,不然认为是过时数据。ok~,关于悲观锁和乐观锁的简单概念就先了解到这。
在mysql中,为了保证数据一致性和防止数据处理冲突,引入了加锁和解锁的技术,这样可使数据库中特定的数据在使用时不让其余用户(进程或事务)操做而为该数据加锁,直到该数据被处理完成后再进行解锁。根据使用目的不一样把锁分为共享锁定(也称为读取锁定)和排他锁定(写入锁定)。
共享锁定:将对象数据变为只读形式的锁定,这样就容许多方同时读取一个数据,此时数据将没法修改。
排他锁定:在对数据进行insert/update/delete时进行锁定,在此时其余用户(进程或事务)一概不能读取数据,从而也保证数据完整性。
经过上述的分析,咱们也理解了事务、锁和隔离级别的概念,但锁和事务以及分离水平关系如何呢?实际上,事务是解决多条sql执行执行过程的原子性、一致性、隔离性、持久性的总体解决方案,而事务分离水平则是并发控制的总体解决方案,其实际是综合利用各类类型的锁来解决并发问题。锁是数据库并发控制的内部基础机制。对应用开发人员来讲,只有当事务分离水平没法解决并发问题和需求时,才有必要在语句中手动设置锁。关于锁的锁定,对于UPDATE、DELETE和INSERT语句,InnoDB会自动给涉及数据集加排他锁(X);对于普通SELECT语句,InnoDB不会加任何锁,事务能够经过如下语句显示给记录集加共享锁或排他锁。请注意InnoDB行锁是经过给索引上的索引项加锁来实现的,也就是说,只有经过索引条件检索数据,InnoDB才使用行级锁,不然,InnoDB将使用表锁。