データベースはロック機構が必要なのはなぜ?何のメカニズムをロックしていますか?

ロックコンセプト:

まずは、データベースロックが何であるかを理解しましょう下、

トランザクションは、データベース内のXianxiangシステムリソース(例えば、テーブル及びレコード)、リソースブロックへのロックアクセス要求される前に、

ロックを取得するトランザクションの後、つまり、トランザクションがそのロックを解放する前に、他のトランザクションは、このデータを更新することができない、データの制御を取得します。トランザクションの撤退後は、ロックされたリソースを解放します。

なぜロック?

    データベースは、ユーザテーブルt_userとして、複数のユーザによって使用される共有リソースである、ブラウザの前に二人の口座番号でログインし、電話番号が変更されました。複数のユーザーが同時にデータにアクセスするとき、それはデータベース内の同じデータにアクセス同時に複数のトランザクションを有することになります。制御されない同時動作は(ダーティ・リード、非反復リード、ファントムを読み出し、等)を読み出し、データベースの一貫性を破壊し、誤ったデータを格納することができる場合、デッドロックが発生する可能性があります。この問題を解決するために、ロックは、データベースの同時実行制御を実現するための非常に重要な技術は良いプログラムです。単にトランザクションがテーブルのレコードを操作する前に、SQL文を実行したときに、入れて、レコードへのアクセスのためのXianxiangデータベース要求は、このトランザクションがロックを解除する前に、他のトランザクションがデータを更新することはできません、あなたのロックを設定します。

データベースのロックカテゴリー:

オプティミスティック・ロック:

オプティミスティック・ロックは、内蔵されていないデータベース、我々は自分自身を実現する必要があります。作りながら、オプティミスティック・ロックは、データベース(更新)の操作は、アイデアは、他の特別な処理(つまり、ロックされていない)、データを扱う場合、この操作は、紛争にはつながらないということは非常に楽観的ではないときにことを意味し更新後に、競合があるかどうかを判断するために行きます。
典型的には、これが実現される:表中のデータ(更新)、データテーブルを操作プラスたびに、操作をバージョン(版)フィールドを与えるときに、バージョン番号を記録する部分がインクリメントされます。それは、その後、あなたがそのレコードのために(更新)操作したい場合は、彼らが同じであれば、現時点では判定値の最初のバージョンは、ちょうどチェックアウト時のバージョンの値に等しい、バージョンフィールドを取得し、歴史の一部をチェックアウトすることですこの期間中に、他のプログラムは、アップデートを実行することができ、それを操作しないように、バージョンフィールドの値がプラス1;値の発見版のバージョンの現時点での値は、更新は、この期間を持っている場合だけ出すために等しくありませんそこに操作する他のプログラムがあり、更新操作が実行されません。
例:
単一の操作は、3つのステップ含む
1照会製品情報

ID =#{ID} t_goodsから(状態、ステータス、バージョン)を選択

2.商品情報母線
3.製品レビューステータス2

更新がt_goods 

設定ステータス = 2、バージョン=バージョン+ 1 

ここで、ID =#{ID}とバージョン=#{バージョン}。

ペシミスティック・ロック:
ロック楽観とは悲観対応するロックです。悲観的ロックが同期するので、悲観的ロックでこのデータ競合が発生するデータを扱う、それは各動作中にロックをすることができ得ることによって、同一のデータ上で動作しなければならない場合、これは、Javaに非常に類似している必要がありますより多くの時間を費やしています。対応するロック楽観に加えて、悲観的ロックは、データベース自体によって達成され、時間を使用し、我々は直接の関連文データベースを呼び出します。
ここでは、他の二つの概念をロックする悲観的ロックが出てきた、彼らは関連する共有ロック排他ロック共有ロックと排他的ロックは、悲観的ロックは、悲観的ロックタリアは、の範囲に属する異なる実装されています。

共有ロック:

Sロックを知られているか、またはロックを読んで、プラス共有ロックデータ・オブジェクトは、他のトランザクションで読み取ることができますが、変更することはできません、一般的にデータオブジェクトが読まれるが完了すると、ロックがすぐに解放されます

排他ロック:

ロックトランザクションの終了がリリースされるまで、またXロックとして知られているか、またはロックを読んで、データオブジェクトが排他ロックと組み合わせた場合、トランザクションは、データオブジェクトにアクセスするためにキーでなければなりません。他のトランザクションの間では、それを読んで、変更することはできません。

ラインロック:
行ロックは、文字通りの意味を理解し、それが記録プラスロックで行ロックを、追加することです。
例えば、ロック声明共有のプレゼンテーションの前に
idは=「街からSELECT *を
原因主キーとして都市テーブル、idフィールドに、それはまた、インデックスと同じです。ロックを行う場合、このインデックスは、IDレコード1プラスロックし、ロックが行ロックです。

補足==>(デッドロックコード

デッドロック:

デッドロックは、外部の力なしで、彼らはそれを促進することができなくなり、によるリソースの競合または起因互いに通信引き起こされるブロッキング現象を、実装プロセス内の2つの以上のプロセスを指します。

これらのプロセスは、常にデッドロックと呼ばれる別のプロセスを待っています

デッドロックのために必要な条件を生成します。

1、互斥使用,即当资源被一个线程使用(占有)时,别的线程不能使用
2、不可抢占,资源请求者不能强制从资源占有者手中夺取资源,资源只能由资源占有者主动释放。
3、请求和保持,即当资源请求者在请求其他的资源的同时保持对原有资源的占有。
4、循环等待,即存在一个等待队列:P1占有P2的资源,P2占有P3的资源,P3占有P1的资源。这样就形成了一个等待环路。

死锁产生的原因:

1) 系统资源的竞争

通常系统中拥有的不可剥夺资源,其数量不足以满足多个进程运行的需要,使得进程在 运行过程中,会因争夺资源而陷入僵局

2) 进程推进顺序非法

进程在运行过程中,请求和释放资源的顺序不当,也同样会导致死锁。例如,并发进程 P1、P2分别保持了资源R1、R2,而进程P1申请资源R2,进程P2申请资源R1时,两者都 会因为所需资源被占用而阻塞。

3)信号量使用不当也会造成死锁。

进程间彼此相互等待对方发来的消息,结果也会使得这 些进程间无法继续向前推进。

如何避免死锁?

三种用于避免死锁的技术:

1)加锁顺序:

一个线程需要一些锁,那么它必须按照确定的顺序获取锁。它只有获得了从顺序上排在前面的锁之后,才能获取后面的锁。

例如,线程2和线程3只有在获取了锁A之后才能尝试获取锁C(获取锁A是获取锁C的必要条件)。因为线程1已经拥有了锁A,

所以线程2和3需要一直等到锁A被释放。然后在它们尝试对B或C加锁之前,必须成功地对A加了锁。

2)加锁时限 :

另外一个可以避免死锁的方法是在尝试获取锁的时候加一个超时时间,这也就意味着在尝试获取锁的过程中若超过了这个时限该线程则放弃对该锁请求。

并会进行回退并释放所有已经获得的锁,然后等待一段随机的时间再重试。这段随机的等待时间让其它线程有机会尝试获取相同的这些锁,

并且让该应用在没有获得锁的时候可以继续运行(加锁超时后可以先继续运行干点其它事情,再回头来重复之前加锁的逻辑)。

3)死锁检测:

每当一个线程获得了锁,会在线程和锁相关的数据结构中(map、graph等等)将其记下。除此之外,每当有线程请求锁,也需要记录在这个数据结构中。

当一个线程请求锁失败时,这个线程可以遍历锁的关系图看看是否有死锁发生。如果检测到死锁,就释放所有锁,回退,并且等待一段随机的时间后再重试

遇到死锁怎么办?

我们先了解下死锁定理: 
                     ①如果资源分配图中没有环路,则系统没有死锁; 
                     ②如果资源分配图中出现了环路,则系统可能有死锁。

从上面的死锁定理中我们可以知道只要打破死锁的环路就可以解开死锁,以下是处理死锁的两种名方法:

1)抢占资源:挂起某些死锁进程,并抢占它的资源,将这些资源分配给其他的死锁进程。但应防止被挂起的进程长时间得不到资源,而处于资源匮乏的状态。

2)终止(或撤销)进程:终止或撤销系统中的一个或多个死锁进程,直至打破死锁状态



(完)

 

おすすめ

転載: www.cnblogs.com/xiaofengwang/p/11291944.html