2017-07-20 13 views
0

私は、キャッシュストレージのためのredisでSpring mvc + Hibernateを使用してマルチスレッドWebアプリケーションを開発しています。私はコントローラやサービスにロックを適用する方法を見つけることに目を向けています。Spring + Hibernate + Redisの分散ロック

私はHibernateが提供するロック機構をデータベースレベルで適用することはできません。ここで

は例です:CampaignBulkControllerでメソッドを作成するためにマップされたリクエストが処理されている間

@RestController 
@RequestMapping(RestConstants.BASE_PATH + "/campaigns") 
Class CampaignController { 

    @RequestMapping(value = "/{id}", method = RequestMethod.GET) 
    public ApiResponse<?> findOne(@PathVariable Integer id) { 
     Campaign campaign = repo.findOne(id); 
     return toResponse(campaign); 
    } 

    @RequestMapping(value = "", method = RequestMethod.POST) 
    public create(@RequestBody Campaign campaign) { 
     //create an campaign here 
    } 

    @RequestMapping(value = "/{id}", method = RequestMethod.PATCH) 
    public update(@RequestBody Campaign campaign) { 
     //update an campaign here 
    } 
} 

@RestController 
@RequestMapping(RestConstants.BASE_PATH + "/bulkCampaigns") 
Class CampaignBulkController { 
    @RequestMapping(value = "/upload", method = RequestMethod.POST) 
    public create(@RequestPart MultipartFile data) { 
     /* 
     Data contains a list of campaigns with their details, 
     controller will iterate through the list and create all the campaigns. 

     */ 
    } 
} 

、キャンペーン上の他のすべての書き込みを扱うが、読み込みすることができない、キャンペーンを更新または作成するための要求であるallowed.Thatです/キャンペーンを削除する必要があります。

複数のサーバーがあり、各サーバーはマルチスレッドです。

私はSpringとHibernateの新機能です。どんなアイデアや提案もありがとうございます!

+0

あなたの説明に基づいて、データベースレベルのような音はあなたのロックを欲するものですか?テーブルをロックすると、他のサービスはテーブルを使用する前にロックが解除されるのを待たなければなりません。 – Kayaman

+0

特別なリクエストが処理されている間に、他のリクエストを削除し、「<特別リクエストの名前>が処理中にリクエストを処理できません。 2)特別リクエストが処理されている場合にのみリクエストが入ってくることを保証する必要があります –

+0

特別リクエストは特別リクエストとは異なるテーブルを共有していますか? – Kayaman

答えて

1

ここでは初期の回答の概要を説明します。

共有のReadWriteLockを使用し、通常の操作に読み取りロックを使用する場合は、書き込み操作ロックを使用して通常の操作をブロックできます。

// Regular operation tries to lock, if not successful a privileged operation is happening 
if(!lock.readLock().tryLock()) 
    return cannotProcessResponse; 

performRegularOperation(); 
lock.readLock().unlock(); 

// Privileged operation always waits for lock 
lock.writeLock().lock(); 
performPrivilegedOperation(); 
lock.writeLock().unlock(); 

今、このアプローチにはいくつかの問題があります。単一の共有ロックを使用する場合、一度に実行できる特権操作は1つだけです。これが問題であれば、複数のロックを使用でき、それらの読み取りロックは一緒にロックされます(デッドロックが発生する可能性があるので、注意が必要です)。ロックの公平性も考慮する必要があります。

+0

複数の特権操作を一度に実行できないように質問を更新しました。どのようにお勧めしますか?ロックを実装する? –

+0

これは簡単になります。共有ロックを使用するだけで(例えば、Beanとして注入する)、私の答えに概説したようにします。もちろん、コードを盲目的にコピーする前に読んでみてください。 – Kayaman

+0

スレッドセーフですか? 1つのBeanを複数のスレッドと複数のWebサーバーに宣言できますか? –

関連する問題