数据库并发控制原理详解

数据库并发控制原理

数据库属于公共资源库,当多个事务并发处理数据库数据时,如果控制不当则会造成数据的不一致性,出现数据混乱。对此,数据库引入了锁机制来解决这一问题。为了弄清这个问题,首先要明白为什么多事务并发时会出现数据的不一致性,这要从数据库事务说起。

那数据库事务是个什么东东呢?其实简而言之,就是多个有关数据库的操作要么都一次性全部完成,要么都不完成。不能出现某些数据库操作执行完了,而另外一些数据库操作失败的情况,一个事务内的所有数据库操作要“同生共死”,梁山好汉的气概啊。事务有以下特点:

原子性:所谓原子性就是不可分割的意思,就好像化学中原子是参与化学反应的基本单位一样。也就是说一个事务中的多个数据库操作是一个整体,不能分割开来,部分执行,部分不执行,要么全部执行,要么都不执行,即是前面所说的“同生共死”的意思。

‚一致性:所谓一致性就是当数据库只包含成功提交事务的结果时,我们就认为数据库处于一致性状态,也就是说最终的结果要符合成功提交事务后的预期值。举个例子吧,有这样一个事务包含两个操作,一个是从A账户取出100元,另一个操作是把这一百元存入B账户中,这两个操作都执行和不都执行时,数据库都处于一致性状态,但是如果前一个操作成功了,而后一个操作失败了,这时数据库就处于不一致状态,因为这不符合一个事务成功提交后的结果预期啊,少了100元啊。可见一致性和前面的原子性密切相关啊。网上有人解释说一致性就是事务执行前后数据的一致性,废话,一致性到底是啥等于没说,而且误导人。

ƒ隔离性:所谓隔离性就是说不同的事务执行之间是相互独立的,互不干扰,这是数据库并发的基础。

④持续性:所谓持续性就是说一旦事务成功提交,其对数据库中数据的改变是永久性的。

事务可以并发,但是对数据的修改必须串行。由数据库事务的原子性和一致性可知,必须一个事务彻底执行完后才能执行另外一个事务,否则就会出现事务并发引起的数据混乱的问题。数据库并发可能出现的问题如下:

丢失修改:两个事务T1T2读入同一数据并修改,T2提交的结果破坏了T1提交的结果,导致了T1的修改丢失。

‚不可重复读:事务T1读取某一数据后,事务T2对其做了修改,当事务T1再次读该数据时,得到的值与前一次不同。

ƒ读脏数据:事务T1修改某一数据,事务T2读取同一数据后,T1由于某种原因被撤销,这时T1修改过的数据恢复原值,T2读到的数据与数据库中的值就会不一致。

产生上述三种数据不一致性的主要原因是并发破坏了事务的隔离性。并发控制就是要用正确的方式调度并发操作,使一个用户事务的执行不受其他事务的干扰,从而避免数据的不一致。

并发控制的主要技术有:封锁、时间戳、乐观控制法。DBMS一般采用封锁的方法。

所谓封锁就是事务T在对某个数据对象操作之前,先向系统发出请求,对其加锁。加锁后事务T对该数据对象有了一定的控制,在事务T释放它的锁之前,其他的事务不能更新此数据对象。而锁又分为排它锁和共享锁:

排它锁又称写锁或悲观锁:若事务T对数据对象A加上X锁,则只允许T读取和修改A,其他任何事务都不能再对A加其他任何类型的锁,直到T释放A上的锁。由排它锁的这个特点可知道悲观锁的并发访问性不好,效率低,因为它是串行存取数据。

共享锁又称读锁或乐观锁:在事务T对数据对象A加上S锁后,则事务T可以读A但不能修改A,其他事务只能对AS锁,不能加X锁,知道T释放A上的锁。这就保证了其他事务可以读取A,但在T释放S锁之前不能修改A。由此特点可知乐观锁以较大的锁粒度获得了较好的并发访问性能。

乐观锁和悲观锁的设计体现了可串行化调度策略和锁方式的基本思想原则 。

可串行化调度策略:

让冲突操作串行执行,非冲突操作并行执行。也就是说事务的并行执行当且仅当其结果与这些事务按某一个次序串行执行时的结果相同时,才是正确的。可串行性是并行事务执行结果正确性的惟一准则

锁方式的基本思想原则 :

事务对任何数据的操作必须先申请该数据项的锁,只有申请到锁后,即加锁成功后,才可以对数据项进行操作。操作结束后,要及时释放已申请的锁。通过锁的共享及排他的特性,实现事务的可串行化调度。

  那么在运用锁时,何时申请锁,持锁时间的确定,何时释放锁等问题需要在对数据对象加锁时约定一些规则加以解决,这就要引入三级封锁协议:

一级封锁协议:事务T在修改数据对象前必须对其加X锁,直到事务结束才释放锁------------->可解决数据“丢失修改”的问题。

二级封锁协议:在一级封锁协议的基础上,如果事务T需要读取数据,则必须对其加S锁,读完后立即释放---------------->可解决“脏读”、“丢失修改”的问题。

三级封锁协议:在一级封锁协议的基础上,加上事务T在读取A之前必须加S锁,直到事务T结束才释放S---------->可解决“脏读”、“丢失修改”、“不可重复读”的问题。

 

数据库事务在程序中的具体应用:

现在我们用的关系式数据库基本上都支持事务的功能。JDBC支持事务,也是依赖于数据库的,connection.commit(),rollback()就是调用数据库的commitrollback。很明显,HIBERNATE/SPRING的事务也是依赖JDBC的。SPRING的声明式事务,利用了AOP,在方法的起点切入事务的起点,在方法调用的终点切入事务的终点(提交),捕获异常中回滚事务。

注:springhibernatejdbc事务的比较(酝酿。。。勿忘写)

                                                                                                                                                     

 

 

 

 

 

 

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值