2016-04-28 16 views
0

私はデータベースにそれを更新するために、休止状態使用方法可変パラメータスレッドセーフな静的メソッド?

public static Person updatePersonId (Person person) 
{ 
    // If the ID of the person reaches the maximum ID in our predefined range in configuration then reset the ID from the start otherwise it will cross the range we defined. 
    if (person.getNewID().longValue() == person.getLastPossibleID().longValue()) 
    { 
     person.setNewID (person.getFirstID()); 
    } 

    // add 1 to Old ID to get new ID 
    person.setNewID (person.getNewID + 1); 

    return person; 
} 

を持っています。

ご覧のとおり、データベースに同じIDの人を1人以上置くことはできません(以前のIDに常に1が追加されるため)。

私のアプリケーションを同時に実行すると、つまり同時に2つのトランザクションが実行されると、人に割り当てられたIDが重複してしまうなどの問題があります。

Database row 

PersonID  PersonName 

    1     Bob 
    2     Robert 
    2     Daniel 

スレッドセーフではないメソッドを作成しましたか?同期キーワードを追加しますか?

+1

私のメソッドはスレッドセーフではありませんか?同期キーワードを追加しますか? NO DBシーケンスを使用する –

+0

@ScaryWombat、OPはサイクリングシーケンスが必要です。 – shmosel

+0

しかし、皆さん、シーケンスなしでこれを行うことはできますか?私のメソッドはスレッドセーフではありませんか?並行性の問題により重複IDが明らかに発生していますか? – Aiden

答えて

1

はい、このメソッドはスレッドセーフではありません。同様に、2つのスレッドがのSametimeでこのラインに達する可能性があります -

person.setNewID (bnkPrb.getNewID + 1); 

は、しかし、全体の方法は、コードをdownthe遅く、これだけの行をロックオンかかりますsyncronizing: -

のpublic static人updatePersonId(人人) {// 者のIDは、構成における当社所定の範囲内の最大IDに到達した場合、それ以外の場合は、我々はしかし

if (person.getNewID().longValue() == person.getLastPossibleID().longValue()) 
{ 
    person.setNewID (person.getFirstID()); 
} 

// add 1 to Old ID to get new ID 
syuncronized(this){ 
person.setNewID (bnkPrb.getNewID + 1); 
} 


return person; 
} 

を定義された範囲を横断する最初からIDをリセットし、BESデータベース側で列またはシーケンスを自動増分するアプローチ。

+0

ヒープありがとう。私は今理解しています:) – Aiden

+0

質問、もし私がシーケンスを使用して、コードを同期しないと、トランザクションがロールバックすると、そこにIDにギャップがあります。 IDに隙間がないことを確認する必要がある場合はどうすればいいですか? – Aiden

+0

本当に必要なのは、これまでに何を取ったのか、それはパフォーマンスを妨げているからです。あなたは次の行動が最初に完了するまで待つ必要があるでしょうから。同期化しても、メソッド全体を同期させる必要があります。 – Panther

関連する問題