Question

I have a backend application, the application doesn't have any user interface. The actions are triggered by incoming data that the server listens for on UDP and TCP port.

We have Customer table, the table has 15 fields. each field represents some key details or pointers to other information. for example,

CUSTOMER_TABLE {
 ID,
 NAME,
 DEFAULT_ADDRESS_ID,
 EMAIL_ADDRESS,
 LAST_LOGIN,
 VERSION   <--- trying to introduce
}

Except for ID, each of these fields can be updated by different processes at a time. I'm having issues when two concurrent process overriding each other's value. So, I introduced VERSION - the hibernate generated version field.

Now suppose Server1 at time T1 picks up Customer modelwith version#400 Server2 at time T1 picks up Customer model with version#400

Server1 changes the EMAIL_ADDRESS and updates the CUSTOMER (at T2), hence the new version number is 401 (hibernate generated).

Server2 changes NAME and attempts to update the CUSTOMER at T3 , since the version number is older than the one in DB, the transaction will fail.

Since the application is a non-user interface app, we can't really ask user to authorize the change... we have to handle it gracefully so that the changes goes through.

What all options do I have to handle this kind of situation ?

The app has following structures

Listening Port Handler -> Service Wrapped in Transaction -> DAO -> DB

and for the next one - here is a disclaimer - I know this is a bad design...but unfortunately, the app has evolved from a non-transactional app to transactional one in a very unplanned way...and I don't have much of control on deciding "when" to fix overall design. Now the structure....

Listening Port Handler -> Service invoked to get the model(ModelX) -> DAO -> DB (yes you are right, the model goes out of transaction boundary ... :-( )
                       -> Invoke different independent operations, each operation wrapped in txn -> DAO -> DB
                       -> Modify Model (ModelX)
                       -> Update model(ModelX) as a separate transaction -> DAO -> DB

I will have trouble in the second one, I can't refresh my model, b'cos if I do so I will lose all that was changed on Model or I will have to repeat all the steps again which can result in other successful operations fired twice (at least)

My question is - is there anyway that

  1. hibernate can understand the attribute that was modified
  2. check version
  3. if version in hand is stale, get new version and apply changes on the new version
  4. save the object (instead of throwing an exception)
Was it helpful?

Solution

One of the options is to use dynamicInsert/dynamicUpdate features of Hibernate. You would have to get rid of the versioning though. Here is an extract from Hibernate documentation:

dynamic-update (optional - defaults to false): specifies that UPDATE SQL should be generated at runtime and can contain only those columns whose values have changed.

An example of this feature can be found here.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top