Optimistic Locking used in a REST API

580 views
Skip to first unread message

Tobias H.

unread,
Jun 5, 2014, 10:34:35 PM6/5/14
to grails-de...@googlegroups.com
Hello,

As far as I came to understand, Optimistic Locking only works in an environment which uses HTTP sessions, or if the access of the domain object really happens concurrently.

In the scenario of a REST API where one user saves an object with version 1, and later another user saves the same object also with version 1, the second write will overwrite whatever the first user wrote.
Shouldn't this case also be handled by the OL mechanism? If not (as I understand it is), it seems to me a bit poor that the programmer has to deal with this situation separately.

Using Grails 2.3.9, Mysql, JDK 1.7.

Thanks,
Tobias

Graeme Rocher

unread,
Jun 6, 2014, 4:23:52 AM6/6/14
to grails-de...@googlegroups.com
I'm not sure what you mean, Optimistic locking has little to do with
HTTP sessions?

The programmer needs to decide how important lost updates are in
relation to their application. Some applications only need to "latest"
version to be definitive, others less so. If your application requires
a high level of transactionality then you should be using pessimistic
writes by passing lock:true to you queries and using @Transactional
around your write operations. Note this comes with a performance cost.

If you do not want to use pessimistic writes then it is up to the
application to decide what to do in the case of a Optimistic Locking
failures case, Grails cannot know what to do here there are many
options... merge the data? inform the user of the other update and ask
the user to merge? Just refresh and perform a retry?

What do you expect to happen with regards to REST?
> --
> You received this message because you are subscribed to the Google Groups
> "Grails Dev Discuss" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to grails-dev-disc...@googlegroups.com.
> To post to this group, send email to grails-de...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/grails-dev-discuss/3d783efe-85bf-43f9-a8ea-4d0f93e16d05%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.



--
Graeme Rocher
Grails Project Lead
SpringSource

Tobias H.

unread,
Jun 6, 2014, 5:09:22 AM6/6/14
to grails-de...@googlegroups.com
Thanks a lot for your answer, Graeme.

I'll try to be more exact.

What we have is something like the person who asked this SO question.
1. So a user A loads an object and does some manipulations.
2. So does user B.
3. User A saves the object with version 1 => version will be incremented to 2
4. User B saves the object with version 1 (might be many minutes later).

Here's a code snippet from the update:
def update(Group groupInstance, Long version) {
  if (version != null) {
    groupInstance.version = version
  }
  groupInstance.save flush:true
  request.withFormat {
    '*'{ respond groupInstance, [status: OK] }
  }
}


What we would want is that in 4, the instance.save() of User B's update request would throw
an exception. But it doesn't. The version is completely ignored. The version gets incremented
the content saved.

What is going wrong?

Thanks,
Tobias

Graeme Rocher

unread,
Jun 6, 2014, 6:37:57 AM6/6/14
to grails-de...@googlegroups.com
What is wrong is that you are overwriting the version with one from
your request, so when it comes to do the version check you have
essentially reset the version to its original value unless I am
missing something. The version field is not something you ever assign
manually it is something assigned and managed internally by Hibernate
>> > email to grails-dev-disc...@googlegroups.com.
>> > To post to this group, send email to grails-de...@googlegroups.com.
>> > To view this discussion on the web visit
>> >
>> > https://groups.google.com/d/msgid/grails-dev-discuss/3d783efe-85bf-43f9-a8ea-4d0f93e16d05%40googlegroups.com.
>> > For more options, visit https://groups.google.com/d/optout.
>>
>>
>>
>> --
>> Graeme Rocher
>> Grails Project Lead
>> SpringSource
>
> --
> You received this message because you are subscribed to the Google Groups
> "Grails Dev Discuss" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to grails-dev-disc...@googlegroups.com.
> To post to this group, send email to grails-de...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/grails-dev-discuss/bd1f6151-ac52-4348-ad8a-e3ada7ab9a8d%40googlegroups.com.

Tobias H.

unread,
Jun 6, 2014, 6:42:58 AM6/6/14
to grails-de...@googlegroups.com
>> managed internally by Hibernate
OK, that's some information I was missing. I was trying to "provoke" the OL-exception by doing this overwriting like an idiot.
As mentioned in the other topic, I think, I'll have to just use this explicit version check.

Thank again for your explanation.
Tobias
>> > To post to this group, send email to grails-de...@googlegroups.com.
>> > To view this discussion on the web visit
>> >
>> > https://groups.google.com/d/msgid/grails-dev-discuss/3d783efe-85bf-43f9-a8ea-4d0f93e16d05%40googlegroups.com.
>> > For more options, visit https://groups.google.com/d/optout.
>>
>>
>>
>> --
>> Graeme Rocher
>> Grails Project Lead
>> SpringSource
>
> --
> You received this message because you are subscribed to the Google Groups
> "Grails Dev Discuss" group.
> To unsubscribe from this group and stop receiving emails from it, send an

Roberto Guerra

unread,
Jun 9, 2014, 11:05:56 AM6/9/14
to grails-de...@googlegroups.com
We use a Retry Strategy for our apps that are SPA or semi-SPA. In most our cases, the business requirement is pretty simple when it comes to version control: the last write wins. So we load the instance of the domain class when the request is made, if an OptimisticLockingException is thrown, we refresh the instance and try again. This is all encapsulated inside a utility class that will try 5 times and throw an exception if it fails after 5 attempts. Before you  try this, make sure your business requirements are okay with it.

Richard Seldon

unread,
Jun 9, 2014, 11:29:31 AM6/9/14
to grails-de...@googlegroups.com

The specific question from the OP that never got answered was not related to what to do AFTER acknowledging an Optimistic Lock related error. 
The question was the behaviour for Optimistic Lock Exception to be raised in the first place.

Here is the scenario as the OP asked it:

1). Grails runs behind a RESTful API using GORM and MySQL backend. Front end is a SPA application with Node proxy.

2). Multiple users interact with the System and potentially 2 or more users could request the same information at the same time. Lets say, two users are both updating a Merchant record with version 2.

3). On the basis that one of them saves their updates, and the version in DB is updated to 3, then the second user attempts to update the same record (with their copy), the expectation is that indeed an OptimisticLockingFailureException would be raised. According to the OP, this NEVER occurs.


In other words, referring to the documentation for Grails 2.3.9:

def airport = Airport.get(10)

try { airport.name = "Heathrow" airport.save(flush: true) } catch (org.springframework.dao.OptimisticLockingFailureException e) { // deal with exception }


This is NOT happening. Instead, the OP has to resort to the following sort of workaround where version are EXPLICITLY checked, rather the more preferable approach above of just handling a raised exception and dealing with it IF it ever happens:

 @Transactional
    def update(Airport airportInstance, Long version) {

        …// validation etc etc


if(version != null && airportInstance.version != version) {
def msg = "Version out of sync: used [${version}], current version is [${airportInstance.version}]"
log.error msg
// deal with this situation...
}

        airportInstance.save flush:true

        // rest of method
}

So the question put forward by the OP was to know what the expected behaviour was. For instance, is there anything particular about usage of Grails via REST, as opposed to keeping detached instances in Session storage and reattaching / merging etc that might be the cause of failure here. Otherwise, it looks like the behaviour does NOT work as expected.

Stackoverflow has a bunch of conflicting information and answers on this point. The OP did share those links too. Reference the following where answers clearly contradict one another, and none is marked as correct. Read the comments under proposed answers and you will see how evident the confusion is.



It would be helpful for the community to receive a definitive answer on this as SOF seems short on clearcut answers.






To unsubscribe from this group and stop receiving emails from it, send an email to grails-dev-disc...@googlegroups.com.

To post to this group, send email to grails-de...@googlegroups.com.

Roberto Guerra

unread,
Jun 10, 2014, 10:31:41 AM6/10/14
to grails-de...@googlegroups.com
There is no difference b/w a REST call and a traditional web application. You still have to load the instance via GORM. I personally haven't used the feature in 2.3 that allows you to expose your domain models. I think that is a bad thing to do. It is okay to play around with, but thats about it. So many bad things can happen when you expose your db directly. 

Also, we use org.grails.datastore.mapping.core.OptimisticLockingException instead of org.springframework.dao.OptimisticLockingFailureException.
Not sure if the exceptions changed in 2.3. We decided to skip 2.3 and wait for 3.0.

Richard Seldon

unread,
Jun 10, 2014, 11:26:26 AM6/10/14
to grails-de...@googlegroups.com
Hi Roberto,

Thank you for your follow up answer. 

A few short follow-up points / thoughts / questions - I would need to get directly involved in a full investigation into the actual behaviour. Going on what I have read so far:

1). Believe you are right regarding difference between REST orchestrated and traditional (JEE container with Hibernate and HTTP Session storage etc) - that line of enquiry slipped into the discussion as part of another StackOverflow Optimistic Locking answer - http://stackoverflow.com/questions/24051407/grails-hibernate-optimistic-locking-in-controller 

2). As a general question are there any known fields which definitely do NOT get deserialised / bound automatically when say the JSON request is deserialised (dateCreated, lastModified, version etc ??). Perhaps this is why the OP was explicitly referencing the version attribute as an arg to the update() method rather than depending on the version to be already present in the body of the request.

3). Has anyone got a working version of Grails 2.3.9 with REST, and optimistic Locking try / catch approach working out of the box? Perhaps this really is a (potential) JIRA issue.  [The type of the OptimisticLockingException is what was given in the 2.3.9 docs that’s all.]

4). Finally, regarding REST support in 2.3.x - it is actually very flexible, and recently wrote a solution using only Controllers to handle the REST specific constructs (annotations / endpoints assignments and so on), and you can tailor the Responses / Requests to conceal or expose what you like. Yeah, annotating the domain objects directly in general might have its downsides for sure.






To unsubscribe from this group and stop receiving emails from it, send an email to grails-dev-disc...@googlegroups.com.

To post to this group, send email to grails-de...@googlegroups.com.

Tobias Hasegawa

unread,
Jun 11, 2014, 4:46:29 AM6/11/14
to grails-de...@googlegroups.com
Hello,

Thanks to all for helping on this issue.

I give here just a summary of what I tried on the optimistic locking on a REST app.

A) Using a query parameter (eg. /abc?version=1, that the SPA retrieves from the request); inside a controller method like "def update(Long version)".
A.1) Setting the version field manually(as suggested from this SO answer):
   instance.properties = params
   instance.version = version
   instance.save flush:true

A.2) Using merge() (as suggested from this SO answer):
   instance.properties = params
   instance.version = version
   instance = instance.merge()
   instance.save flush:true
   // or
   instance.properties = params
   instance = instance.merge()
   instance.version = version
   instance.save flush:true

B) Using "version(bindable:true)" in the domain class
In the domain class definition the constraint "version(bindable:true)" can be added, so that this field is automatically bound to the domain instance. I would assume that should also work for automatically created fields (dateCreated, lastModified), but haven't tried that out.

B.1) Using auto-scaffolding
   def update(Group groupInstance) {
      // groupInstance contains "version" sent via PUT body
      // ...
      groupInstance.save flush: true
   }

B.2) Populating data with "properties":
   instance.properties = params
   // instance contains "version" sent via PUT body
   instance.save flush:true
  
As Graeme pointed out the setting version manually will not work. But going through B) sending the version as part of the data body and setting the version field not manually as in A), does not  change anything: the "save()" does not throw an exception either. Whatever the sent version is, when saved it is ignored as when set manually. I think, this is counter-intuitive. This is like a feature that can't be made use of.

On Richard's Point 1 and 3)
For a REST application the optimistic locking seems not supported by Grails. Reading the docs one (I at least) can get the feeling that it should just work. It would be great if the documentation could say a few words on that issue. Since I am not the only one having trouble with this issue, it might be worthwhile opening a JIRA issue.

Regards,
Tobias




--
You received this message because you are subscribed to a topic in the Google Groups "Grails Dev Discuss" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/grails-dev-discuss/rTrlvyh8ubc/unsubscribe.
To unsubscribe from this group and all its topics, send an email to grails-dev-disc...@googlegroups.com.

To post to this group, send email to grails-de...@googlegroups.com.

Graeme Rocher

unread,
Jun 11, 2014, 5:03:43 AM6/11/14
to grails-de...@googlegroups.com
As I already mentioned you NEVER, EVER, EVER set the version manually,
I don't know what you are trying to achieve by doing so, even though
this is effectively what merge() does I cannot recommend you ever do
it in application code. You're essentially overriding the version
loaded by Hibernate from the database and fooling Hibernate into
persisting the data. The 'version' field is something managed
internally and set by Hibernate only.

You can however do a manual comparison to check whether the version
loaded from the db is newer than the version submitted before
attempting an update to your object. Example:

def version = params.int('version')
if(instance.version > version) {
// show error to user or respond with error or merge data manually
}
else {
// perform update
}

However even the above will not guarantee never receiving an
OptimisticLockingFailureException as two concurrent threads executing
an update at the same time could result in the error. The only way to
effectively deal with the exception is to catch
OptimisticLockingFailureException and deal with it some how whether
that is sending and error response to the user saying "sorry someone
performed and update in meantime" or just allowing a "last write wins"
policy by refreshing the object from the database applying the update
again and saving.

I don't understand your assertion that "For a REST application
optimistic locking seems not supported by Grails". Frankly optimistic
locking works exactly the same whether you are using a browser or via
REST. There is no difference in the behaviour. The fact that you are
essentially breaking the behaviour of this feature by manually
assigning the version appears to the source of your confusing.

Cheers
>>>>> >> > email to grails-dev-disc...@googlegroups.com.
>>>>> >> > To post to this group, send email to
>>>>> >> > grails-de...@googlegroups.com.
>>>>> >> > To view this discussion on the web visit
>>>>> >> >
>>>>> >> >
>>>>> >> > https://groups.google.com/d/msgid/grails-dev-discuss/3d783efe-85bf-43f9-a8ea-4d0f93e16d05%40googlegroups.com.
>>>>> >> > For more options, visit https://groups.google.com/d/optout.
>>>>> >>
>>>>> >>
>>>>> >>
>>>>> >> --
>>>>> >> Graeme Rocher
>>>>> >> Grails Project Lead
>>>>> >> SpringSource
>>>>> >
>>>>> > --
>>>>> > You received this message because you are subscribed to the Google
>>>>> > Groups
>>>>> > "Grails Dev Discuss" group.
>>>>> > To unsubscribe from this group and stop receiving emails from it,
>>>>> > send an
>>>>> > email to grails-dev-disc...@googlegroups.com.
>>>>> > To post to this group, send email to grails-de...@googlegroups.com.
>>>>> > To view this discussion on the web visit
>>>>> >
>>>>> > https://groups.google.com/d/msgid/grails-dev-discuss/bd1f6151-ac52-4348-ad8a-e3ada7ab9a8d%40googlegroups.com.
>>>>> >
>>>>> > For more options, visit https://groups.google.com/d/optout.
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> Graeme Rocher
>>>>> Grails Project Lead
>>>>> SpringSource
>>>
>>>
>>> --
>>> You received this message because you are subscribed to the Google Groups
>>> "Grails Dev Discuss" group.
>>> To unsubscribe from this group and stop receiving emails from it, send an
> https://groups.google.com/d/msgid/grails-dev-discuss/CABtOk8Q6oSXH%2BryBHwhWBvKLyMAM%2BHGHnxqDodP8AYFWhq%3DoLg%40mail.gmail.com.

Richard Seldon

unread,
Jun 11, 2014, 5:25:33 AM6/11/14
to grails-de...@googlegroups.com
Hi Graeme,

Still not sure you understand what the OP is asking you.

try / catch OptimisticLockingFailureException does NOT work according their test results.

> The only way to
> effectively deal with the exception is to catch
> OptimisticLockingFailureException and deal with it some how

The point being made by the OP is that the OptimisticLockingFailureException NEVER gets invoked. Even if the version is present, the PUT request gets processed and the version updated to one above whatever the database previously had. Any older version gets completely omitted.

Is that a JIRA request? Or do the Grails Core team believe that try / catch should work fine from a RESTful Controller?

This might be an apples versus oranges conversation - just a misunderstanding on how Optimistic Locking is supposed to work. Does there have to be a specific concurrency about the 2 requests (both happening on the server with Hibernate sessions both running) for Optimistic Locking failure to occur - can one request come in, update the DB version, then later after the first HTTP request completed by user 1, second request comes in from user 2 (with older version) and expect an Optimistic Lock failure to arise ? Please clarify this point too.


> As I already mentioned you NEVER, EVER, EVER set the version manually


The OP acknowledges your advice here, they were just trying out workarounds recommended by users on SOF who are saying you CAN do that.
This includes one answer from someone that has made 1800 Hibernate related answers on SOF and has a reputation of 300K. They might indeed be wrong, but certainly their proposal was deemed credible enough to at check as a workaround… The OP, as far I can tell, was not questioning your knowledge here, just trying to get a workaround somehow through trial and error.

As always, we certainly appreciate your expert knowledge on these matters!

Best regards,
> To view this discussion on the web visit https://groups.google.com/d/msgid/grails-dev-discuss/CAO_wNoeTgDuvTwhmvB%2BOe200Ex%3DRVxnzvV-d0O_%2BebjGChmcLA%40mail.gmail.com.

Roberto Guerra

unread,
Jun 11, 2014, 7:12:44 PM6/11/14
to grails-de...@googlegroups.com
The OP should submit a JIRA and a sample application that replicates the issue. I would believe an exception is being thrown, if not the one he is looking for. I've run into the Optimistic Locking issue and I resolved it with a try-catch. I had to do this as recently as 2 weeks ago.
>>>>>>>>> To post to this group, send email to
>>>>>>>>> grails-de...@googlegroups.com.
>>>>>>>>> To view this discussion on the web visit
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> https://groups.google.com/d/msgid/grails-dev-discuss/3d783efe-85bf-43f9-a8ea-4d0f93e16d05%40googlegroups.com.
>>>>>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> --
>>>>>>>> Graeme Rocher
>>>>>>>> Grails Project Lead
>>>>>>>> SpringSource
>>>>>>>
>>>>>>> --
>>>>>>> You received this message because you are subscribed to the Google
>>>>>>> Groups
>>>>>>> "Grails Dev Discuss" group.
>>>>>>> To unsubscribe from this group and stop receiving emails from it,
>>>>>>> send an
>>>>>>> To post to this group, send email to grails-de...@googlegroups.com.
>>>>>>> To view this discussion on the web visit
>>>>>>>
>>>>>>> https://groups.google.com/d/msgid/grails-dev-discuss/bd1f6151-ac52-4348-ad8a-e3ada7ab9a8d%40googlegroups.com.
>>>>>>>
>>>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> Graeme Rocher
>>>>>> Grails Project Lead
>>>>>> SpringSource
>>>>
>>>>
>>>> --
>>>> You received this message because you are subscribed to the Google Groups
>>>> "Grails Dev Discuss" group.
>>>> To unsubscribe from this group and stop receiving emails from it, send an
>>>> To post to this group, send email to grails-de...@googlegroups.com.
>>>> To view this discussion on the web visit
>>>> https://groups.google.com/d/msgid/grails-dev-discuss/604a112a-08bc-4439-ae7e-3856f77f45bc%40googlegroups.com.
>>>> For more options, visit https://groups.google.com/d/optout.
>>>>
>>>>
>>>
>>> --
>>> You received this message because you are subscribed to the Google Groups
>>> "Grails Dev Discuss" group.
>>> To unsubscribe from this group and stop receiving emails from it, send an
>>> To post to this group, send email to grails-de...@googlegroups.com.
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/grails-dev-discuss/e8573340-c64f-4e2d-aa92-d67216d03f19%40googlegroups.com.
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>>
>>> --
>>> You received this message because you are subscribed to a topic in the
>>> Google Groups "Grails Dev Discuss" group.
>>> To unsubscribe from this topic, visit
>>> https://groups.google.com/d/topic/grails-dev-discuss/rTrlvyh8ubc/unsubscribe.
>>> To unsubscribe from this group and all its topics, send an email to
>>>
>>> To post to this group, send email to grails-de...@googlegroups.com.
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/grails-dev-discuss/BD49BD26-2542-47C9-8A64-293F10DF5F09%40gmail.com.
>>>
>>> For more options, visit https://groups.google.com/d/optout.
>>
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "Grails Dev Discuss" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> To post to this group, send email to grails-de...@googlegroups.com.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/grails-dev-discuss/CABtOk8Q6oSXH%2BryBHwhWBvKLyMAM%2BHGHnxqDodP8AYFWhq%3DoLg%40mail.gmail.com.
>>
>> For more options, visit https://groups.google.com/d/optout.
>
>
>
> --
> Graeme Rocher
> Grails Project Lead
> SpringSource
>
> --
> You received this message because you are subscribed to the Google Groups "Grails Dev Discuss" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to grails-dev-discuss+unsub...@googlegroups.com.

Richard Seldon

unread,
Jun 11, 2014, 7:29:46 PM6/11/14
to grails-de...@googlegroups.com
Hi Roberto,

As always, thank you for your prompt responses. Yes, a JIRA and sample app can be provided. Will discuss this with the OP (work colleague).

Quick clarification please - there is an implicit understanding that the Optimistic Locking would always apply even when two requests are entirely sequential. As put in the previous email:

User 1: Gets a form with Merchant1 V2
User 2: Gets a form with Merchant1 V2
User 2: Completes the form and submits - DB now at Merchant1 V3. User 2 switches off their computer and goes for a beer.
User 1: (5 minutes later) Eventually completes the form and submits —  Hibernate checks the version and discovers it is V2, whereas DB is V3. Exception raised.
User 1 curses, has to review the changed data, then redo their entire form. User 1 misses last orders at the pub.

Please can you just confirm the above is the agreed behaviour. Yes, a newbie question - but I just want to ensure we are on the same page. SOF is full of conflicting answers on this, with lots of references to concurrent access in hibernate sessions and so on.

 I had to do this as recently as 2 weeks ago.

As you said in previous email, you are not working with Grails 2.3.x, or Restful Controllers.  

Thank you!




To unsubscribe from this group and stop receiving emails from it, send an email to grails-dev-disc...@googlegroups.com.

To post to this group, send email to grails-de...@googlegroups.com.

Roberto Guerra

unread,
Jun 11, 2014, 8:10:04 PM6/11/14
to grails-de...@googlegroups.com
Yes, that should be the expected behaviour.
...

Aaron

unread,
Jun 11, 2014, 10:25:41 PM6/11/14
to grails-de...@googlegroups.com
This is a common misconception of how optimistic locking should work when dealing with web applications. 

The hibernate optimistic locking behavior will detect and throw an exception if the instance you have loaded has changed between being fetched and saved. In the case that user A loads something and makes changes the flow looks like this:

1. User A loads object and renders view
2. User B loads object and renders view (same object)
3. User A submits a change to the object, incrementing it's version to 1
4. User B submits a change to the object. This is where the confusion lives: that object is reloaded into a new session before data binding, therefore it pulled in the version = 1.
5. The changes from B will overwrite user A changes and version will be 2.

Note that calling Foo.lock() also does not solve this problem because the lock does not span the entire scope of the initial get and subsequent save.

As Graeme said, the proper way to handle this scenario is the store the original version in a hidden field and resubmit it in order to validate manually in the controller. I.e., when user B in step 4 fetches the object, it will see that the version is now 1 but the original version it loaded was 0 and fail.

Hibernate would throw an exception if the two users submitted their requests at the same time and the order looked like this:

1. User A, Object.get()
2. User B, Object.get()
3. User A, Object.save()
4. User B, Object.save() -> Throws optimistic locking exception.
...

Tobias Hasegawa

unread,
Jun 11, 2014, 10:47:58 PM6/11/14
to grails-de...@googlegroups.com
Aaron, thanks a lot for the clarification. After your explanation it makes sense to me why it works the way it does.
So, if that's the way it was meant to be, I accept this and will finally shut up about it.

Tobias


To unsubscribe from this group and all its topics, send an email to grails-dev-disc...@googlegroups.com.

To post to this group, send email to grails-de...@googlegroups.com.

Richard Seldon

unread,
Jun 12, 2014, 12:18:41 AM6/12/14
to grails-de...@googlegroups.com
Hi Aaron,

Thank you for your answer! Yes, we have a “session per request” model using REST calls with no session state between calls.

Lets mark this thread as closed. 

So wrapping this up, couple of other considerations for web apps using session storage that might provide longer lived optimistic lock management...

"session-per-request-withdetached-objects” - If you need a long-running application transaction, you might, thanks to detached objects implement similar to “session per request”. Using detached objects you could you could load the interesting objects in a first Session and later reattach them to a new Session after they’ve been modified by the user. Hibernate will automatically perform a version check. The time between (S1, T1) and (S2, T2) can be “long,” as long as your user needs to make his changes. 

"session-per-applicationtransaction" or "long session” - A single Session that spans multiple requests to implement your application transaction. In this case, you don’t need to worry about reattaching detached objects, since the objects remain persistent within the context of the one long-running Session. Of course, Hibernate is still responsible for performing optimistic locking.  A Session is serializable and may be safely stored in the servlet HttpSession, for example. The underlying JDBC connection has to be closed, of course, and a new connection must be obtained on a subsequent request. You use the disconnect() and reconnect() methods of the Session interface to release the connection and later obtain a new connection.

 



To unsubscribe from this group and stop receiving emails from it, send an email to grails-dev-disc...@googlegroups.com.

To post to this group, send email to grails-de...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages