数据库通常允许多个用户共享数据信息资源,所以必须对并发的事务进行控制,防止多用户并发使用数据库时造成数据错误,以保证数据的完整性。
事务的概念:
事务是用户定义的一个数据库操作序列,这些操作要么全做,要么全不做,是一个不可分割的很小的工作单位。
数据库通过加锁的方式控制并发,其中有两种锁:
共享锁(S锁):
又称读锁,若事务T对数据对象A加S锁,则事务T可以读A但不能修改A,其他事务只能对A加S锁,而不能加X锁,直到事务T释放A上的S锁。这保证了其他事务可以读A,而在事务T释放A上的S锁之前不能对A进行修改。
排它锁(X锁):
又称写锁,若事务T对数据对象A加上X锁,则事务T可以修改A也可以读A,其他事务不能再对A加任何锁,直到事务T释放A上的锁。这意味着在事务T释放A上的锁之前其他事务不能修改和读取A。
在对数据进行加锁时,需要约定并执行一些规则和协议,包括何时申请锁、保持锁的时间以及何时释放等,这些规则就称为封锁协议:
一级封锁协议:
事务T在修改数据A之前必须先对其加X锁,直到事务结束才释放。事务结束包括正常结束(COMMIT)和非正常结束(ROLLBACK)。
一级封锁协议可以防止丢失修改,并保证事务T是可恢复的。使用一级封锁协议可以解决丢失修改问题。在一级封锁协议中如果仅仅是读数据则不进行加锁,因此不能保证可重复读和不读脏数据。
二级封锁协议:
一级封锁协议加上事务T在读取数据A之前必须对其加S锁,读完后方可释放S锁。
二级封锁协议除了防止丢失修改,还可以进一步防止读脏数据。但在二级封锁协议中读完数据后就释放锁,所以不能保证可重复读。
三级封锁协议:
一级封锁协议加上事务T在读取数据A之前必须先对其加S锁,直到事务结束才释放。
三级封锁协议除了防止丢失修改和读脏数据之外,还进一步防止了不可重复读。
三级封锁协议的区别在于什么操作需要申请锁,以及何时释放。
MYSQL还提供了行级锁、表级锁和业级锁
行级锁:
引擎INNODB,仅对指定的一行记录进行加锁,这样其他进程可以对同一个表中的其他记录进行操作
表级锁:
引擎MyISAM,即锁住整个表可以同时读,写不行,在锁定期间,其他线程无法对该表进行写操作;如果是写锁,那么其他线程读也不允许
页级锁:
引擎BDB,一次锁定相邻的一组记录
网友评论