Sharing a Java synchronized block across a cluster, or using a global lock?

前端 未结 5 1277
死守一世寂寞
死守一世寂寞 2021-02-01 07:14

I have some code that I want to only allow access to by one thread. I know how to accomplish this using either synchronized blocks or methods, but will this work i

相关标签:
5条回答
  • 2021-02-01 07:32

    You can use a in-memory-data-grid like http://www.hazelcast.com/ for this too. This is a distributed data structure that supports locking.

    0 讨论(0)
  • 2021-02-01 07:42

    Yes, you are correct in that synchronized blocks won't work across a cluster. The reason is, as you stated, that each node has its own JVM.

    There are ways, however, to get synchronized blocks to work in a cluster as they would work in a single-node environment. The easiest way is to use a product like Terracotta, which will handle the coordination of threads between different JVMs so that normal concurrency controls can be used across the cluster. There are many articles explaining how this works, like Introduction to OpenTerracotta.

    There are other solutions, of course. It mostly depends on what you really want to achieve here. I wouldn't use database locks for synchronizing if you need to scale, as DB doesn't. But I really urge you to find a ready-made solution, because messing around with cluster synchronization is messy business :)

    0 讨论(0)
  • 2021-02-01 07:43

    Couldn't you simply lock the table (or entire db) for updates, so when the first node in obtained the lock all other nodes would not be able to write. Subsequent nodes would wait, and when the lock is released the code would be updated so no record update would be required.

    0 讨论(0)
  • 2021-02-01 07:49

    You are correct that synchronization across processes will not work using the Java synchronization constructs. Fortunately, your problem really isn't one of code synchronization, but rather of synchronizing interactions with the database.

    The right way to deal with this problem is with database level locks. Presumably you have some table that contains a db schema version, so you should make sure to lock that table for the duration of the startup/upgrade process.

    The precise sql/db calls involved would probably be more clear if you specified your database type (DB2?) and access method (raw sql, jpa, etc).

    Update (8/4/2009 2:39PM): I suggest the LOCK TABLE statement on some table holding the version # of the schema. This will serialize access to that table preventing two instances from running through the upgrade code at once.

    0 讨论(0)
  • 2021-02-01 07:53

    Since you are talking about 2 machines, you don't even have shared memory so there is nothing to synchronize.

    We do something similar with our database. This is achieved by adding record versioning in the table. This is what you should do,

    1. Add a column for record/row version.
    2. Go through the logic to check if record needs to be updated.
    3. When you update record, make sure the record version in DB is the same as what you have.
    4. Bump up version every time you write to the database.

    You should only have one server updating the database if you follow these rules.

    0 讨论(0)
提交回复
热议问题