一、数据库并发性
指的是多个事务可以同时访问数据库中的数据。当多个事务在数据库中并发执行时,数据的一致性可能受到破坏,从而导致数据出现问题。
二、数据库访问的并发性问题
更新丢失
当多个事务同时对数据库的同一条记录修改时,后修改的会覆盖前面修改的。
脏读
当A事务对数据库的一条记录进行修改时,但并没有提交,这时B事务读取了这条记录,且A事务进行了回滚,这时B事务读取的数据就是脏读。
不可重复读
一个事务同一条记录读取了两次,但结果不相同。事务A读取数据后,事务B对该条数据进行了修改,事务A再次读取时,两次的结果就不一样。
幻象读
两次执行同一条语select句但得到的结果不同,当第一次执行完select语句时,另一个事务执行了一条insert语句,这时在执行一次select语句,查询的结果就不一样。
三、事务
就是用户定义的一系列数据库操作,这些操作可以视为一个完成的逻辑处理工作单元,要么全部执行,要么全部不执行,是不可分割的工作单元。
3.1事务的四个特性(ACID)
原子性(Atomicity)
原子性是事务包含的所有操作要么全部成功,要么全部失败回滚,因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响。
一致性(consistency)
一致性是事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。
隔离性(isolation)
隔离性是当多个用户并发访问数据库时,数据库为每个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。
持久性(Duravility)
持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变是永久性的,即便在数据库系统遇到故障的情况下也不会丢失提交事务的操作。
3.2事务的隔离等级
Read uncommitted(未授权读取、读未提交)
如果一个事务已经开始写数据,则另外一个事务则不允许同时进行写操作,但允许其他事务读此行数据。该隔离级别可以通过“排他写锁”实现。这样就避免了更新丢失,却可能出现脏读。也就是说事务B读取到了事务A未提交的数据。
Read committed(授权读取、读提交)
读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行。该隔离级别避免了脏读,但是却可能出现不可重复读。事务A事先读取了数据,事务B紧接了更新了数据,并提交了事务,而事务A再次读取该数据时,数据已经发生了改变。
Repeatable read(可重复读取)
可重复读是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,即使第二个事务对数据进行修改,第一个事务两次读到的的数据是一样的。这样就发生了在一个事务内两次读到的数据是一样的,因此称为是可重复读。读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。这样避免了不可重复读取和脏读,但是有时可能出现幻象读。(读取数据的事务)这可以通过“共享读锁”和“排他写锁”实现。
Serializable(序列化)
提供严格的事务隔离。它要求事务序列化执行,事务只能一个接着一个地执行,但不能并发执行。如果仅仅通过“行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作的事务访问到。序列化是最高的事务隔离级别,同时代价也花费最高,性能很低,一般很少使用,在该级别下,事务顺序执行,不仅可以避免脏读、不可重复读,还避免了幻像读。
四、锁机制
悲观锁
就是某个事务在更新数据过程中将数据锁定,其他任何事务都不能读取或修改,必须修改完成后才能访问数据(类似java的线程同步锁机制)
select * from table_name where id = 1 for update 悲观锁
特点具有排他性 适应使用短事务处理
乐观锁
乐观锁并不是一种数据库的锁机制,而是一种冲突检查机制(版本冲突检测机制和时间戳冲突检测机制),他的特点就是并发性较好,事务修改数据时,其他事务人可以修改数据。
版本冲突检查机制:
即每个数据表中有一个版本字段version,某一个事务更新数据后版本号加1,另一个事务更新后再加1,当事务发现数据库当前版本号于读取数据时版本号不一致时,说明数据已被更改,所以不更改数据。
乐观与悲观的优缺点
悲观锁的优点是可以保障数据库的数据是绝对安全的,它是依赖数据库的锁机制,能很好的解决数据库访问的并发性问题,但是缺点就是会导致数据库访问性能低下,所以适合短事务(也就是事务执行时间很短)的情况。你想一想,如果事务执行时间很长,那么后面的事务就得一直排队等待嘛。它的使用场景是对数据安全性要求非常高的场景,比如银行系统、金融系统等。
乐观锁的优点是可以保障并发性比较好,也就景数据库访问性能可以,它是依赖软件的冲突检测机制实现的,但是缺点就是并没彻底解决数据库访问的并发性问题,所以数据库的数据不是绝对安全的。它的使用场景是对数据安全性要求不高而对性能要求很高的场景,比如各种信息管理系统等。