質問

In my application I have:

  1. Users.
  2. Database storing list of sth for users (user has id, and I have table ListOfSth containing filed user_id).
  3. Server sending data to users.
  4. Clients - application on users sides.

User can use many clients. Each client can create and update any of user's sth. Requests from user's are handled by server asynchronously.

Problem: How to synchronize user's data?

First idea: integer as version number. User's client has saved his current version number. On synchronization server sends data with version higher than client's current version. Client updates his current version to highest version from received data.

It doesn't work: There could be asynchronous modification: mod1 and mod2. Both started on version X. If mod1 ends, then one of client synchronize (it gets version X+1) and then mod2 ends (with version X+1), this client never gets data modified in mod2.

I can't find out solution, which would work no matter what.

Is there any pattern how to do such thing?

I need it working with MS SQL and Azure SQL databases and VS C# server, with Entity Framework.

役に立ちましたか?

解決

On a MS SQL server, you have a handy data type, timestamp, that allows you to do this quite easily. The update will then look like this:

update [table] set ... where [Id] = @Id and [Version] = @Version;

(the version will be automatically updated if the update comes through, so you don't need to change it manually)

So, if someone modified the row in the meantime, this will modify zero rows (you can check this easily), and if not, you'll push your changes and the version number has a new value automatically.

Even if you don't have something like the timestamp data type, the approach still works as long as you make the change in a single update (or, depending on the transaction model, a single transaction). The key here is the where clause, which forbids you to change anything if the version in DB isn't the one you loaded before you started your changes. Using this, you can simply do

update [table] set ..., [Version] = @Version + 1 
where [Id] = @Id and [Version] = @Version;

This effectively works the same way as with the timestamp data type - if someone increased the version in the meantime, your update isn't going to update anything.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top