2016-12-27 4 views
1

信頼できるコレクションの使用についてはthisの記事を読んでください。信頼できるコレクションにオブジェクトを変更してはいけません。値のコピー(クローン)を取得し、クローンされた値をチェクニングして、RC内のクローンされた値を更新することです。サービスファブリックの信頼できるコレクションの元のオブジェクトを変更する

悪い使用:

using (ITransaction tx = StateManager.CreateTransaction()) { 
    // Use the user’s name to look up their data 
    ConditionalValue<User> user = 
     await m_dic.TryGetValueAsync(tx, name); 

    // The user exists in the dictionary, update one of their properties. 
    if (user.HasValue) { 
     // The line below updates the property’s value in memory only; the 
     // new value is NOT serialized, logged, & sent to secondary replicas. 
     user.Value.LastLogin = DateTime.UtcNow; // Corruption! 
     await tx.CommitAsync(); 
    } 
} 

私Quesionは次のとおりです。私はRCにそれを与えた後に、なぜ私は、オブジェクトを変更することはできませんか?なぜオブジェクトを変更する前にオブジェクトをクローンする必要がありますか?なぜ同じようなことをすることができないのですか(同じトランザクションでオブジェクトを更新することはできません):

using (ITransaction tx = StateManager.CreateTransaction()) { 
    // Use the user’s name to look up their data 
    ConditionalValue<User> user = 
     await m_dic.TryGetValueAsync(tx, name); 

    // The user exists in the dictionary, update one of their properties. 
    if (user.HasValue) { 
     // The line below updates the property’s value in memory only; the 
     // new value is NOT serialized, logged, & sent to secondary replicas. 
     user.Value.LastLogin = DateTime.UtcNow; 

     // Update 
     await m_dic.SetValue(tx, name, user.Value); 

     await tx.CommitAsync(); 
    } 
} 

ありがとう!

答えて

2

技術的には、あなたが望むことができます。しかし、ロックモードと独立性レベルを忘れないでください。
Here we can read: "任意の反復可能な読み取り操作は、デフォルトで共有ロックを使用します。ただし、反復可能読み取りをサポートする読み取り操作の場合、ユーザーは共有ロックの代わりに更新ロックを要求することができます。

つまり、TryGetValueAsyncは共有ロックのみを取得します。この値を後で更新しようとするとデッドロックが発生する可能性があります。
次の文は次のとおりです。「更新ロックは、後で複数のトランザクションによってリソースがロックされて一般的なデッドロックが発生するのを防ぐ非対称ロックです。

await m_dic.TryGetValueAsync(tx, name, LockMode.Update) 
2

信頼できる辞書は複製されたオブジェクトストアです。信頼性の高い辞書(例:TryUpdateAsync)を通過させずに信頼できる辞書内のオブジェクトを更新すると、状態が破損する可能性があります。

たとえば、参照を使用して信頼できるディクショナリ内のオブジェクトを変更すると、変更はセカンダリレプリカに複製されません。 信頼できるディクショナリは、あなたがTValueの1つを変更したことを知らないためです。したがって、レプリカがフェイルオーバーすると変更は失われます。

上記は最も簡単な例です。オブジェクトを直接変更すると、ACIDを複数の方法で破るような重大な問題が発生する可能性があります。

関連する問題