数据库并发问题、事务隔离级别以及数据库锁

一、数据库并发问题

    多用户数据库当多个用户同事操作数据库中的数据时可能会发生的并发问题,总结为以下三类:

    1. 脏读(Dirty Reads):无效数据读出。

    事务1修改了数据库中的一条数据,事务2读取并使用了这条数据,之后事务1出现异常(或其他原因)撤消了对数据的修改。正常情况事务1所操作的数据应该认为没发生任何变化,而实际事务2读取并使用的无效的数据。

    2. 不可重复读(Non-reaptable Reads):在数据库访问中,一个事务范围内两个相同的查询却返回了不同数据。

    ① 事务1读取了数据库中的某些数据,事务1没有结束。事务2对事务1读取的数据进行了更新。事务1再次读取相同的数据却返回了不同的结果。由于事务之间的独立性,事务不知道其他的存在。事务1两次执行相同的查询,返回了不同的结果,如同不能重复读取相同的数据一样。

    ② 幻读:在事务1两次读取数据之间,事务2执行了插入或者删除操作,导致事务1第二次读取出现了第一次读取中没有的数据,或者缺少了第一次读取中出现的数据。

    3. 丢失更新(Lost update): 第一类丢失更新,多个事务查询同一数据,并基于查询结果对数据进行更新。前面的事务更新成功之后,如果后面执行的事务发生回滚,会撤销已经成功的事务的操作。

    4. 第二类丢失更新:多个事务查询同一数据,然后基于查询结果对数据进行更新,最后一个事务的操作会覆盖之前的事务对该数据的更新。


二、事务隔离级别

    为了避免以上问题,标准sql规范中定义了4个事务隔离级别,隔离级别越高越能保证数据的完整性和一致性,但是并发性能(支持多用户同事访问数据库的能力)越差。隔离级别由低到高依次为:

    1. Read Uncommitter(读取未提交数据)

    允许脏读,但是不允许丢失更新。如果一个事务已经开始写数据,则另一个事务不允许对同一个数据进行写操作,但是允许其他事物读取此数据。该隔离级别可以通过“排他写锁”实现。

    2. Read Committed(读取已提交数据)

    允许不可重复读,但是不允许脏读。可以通过"瞬间共享读锁"和”排他写锁“实现。读取数据的事务允许其他事务继续访问该数据,但是未提交的写数据将会禁止其他事务访问。

    3. Repeatable Read(课重复读)

    禁止不可重复读和脏读,但是有时会出现幻读。可以通过”共享读锁“和”排他写锁“实现。读取数据的事务将会禁止写事务(但是允许读事务),写事务则禁止任何其他事务。

    4. Serializable(序列化)

    提供严格的事务隔离。事务只能一个接一个的执行,不能并发执行。仅通过行级锁是无法保证事务序列化的,必须通过其他机制保证新插入的数据不会被执行查询操作的事务访问到。

    多数的数据库应用程序优先把数据库隔离级别设置为Read committed,它能够避免脏读取,而且具有较好的并发性能。尽管它会导致不可重复读、幻读和第二类丢失更新的并发问题,在可能出现这类问题的个别场合,可以由应用程序采用乐观锁或悲观锁来控制。


二、锁

    1. 共享锁

    共享锁又称“读锁”。对于已加共享锁的数据,其他事务可以读取该数据(也就是附加共享锁),但是不能对数据进行更新(也就是附加排他锁)。同一时间同一数据上可以有多个共享锁。

    2. 排它锁

    排它锁又称“写锁”、“独占锁”。对于已加排它锁的数据,其他事务既不能读取该数据,也不能更新该数据。同一时间同一数据上只能有一个排它锁。

    3. 更新锁

    更新锁用于防止常见形式的死锁。

    死锁的例子如下,T1、T2是两个事务:

    T1:

select * from table_name;
update table_name set column_name = new_value where 查询条件;
    T2:

select * from table_name;
update table_name set column_name = new_value where 查询条件;
    假设T1、T2同时到达select语句,双方都对数据加共享锁,根据锁机制,执行完select需要将共享锁升级为排它锁才能更新数据。在升级排它锁之前,必须等待数据上的其他共享锁释放。这样T1、T2都持有共享锁而等待对方释放共享锁,死锁就产生了。

    更新锁表示持有它的事务在执行读操作,但是已经获得在数据上升级排它锁进行更新操作的资格,在事务进行更新操作之前,其他事务还可以读取该数据。一个数据上只能放置一个更新锁。

    更新锁为了解决死锁问题而存在,所以它既有共享锁的特性(允许其他事务读取加锁的数据,从而提高并发性能),又有排它锁的特性(同一数据同一时间只能加一把锁,从而避免多个事务等待对方释放锁资源导致的死锁)。

   


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值