Optimistic Concurrency Control

343 views
Skip to first unread message

Roberto

unread,
May 30, 2011, 9:56:34 AM5/30/11
to Lift
Hello Everyone,

I'm having a question about the Lock Optimistic and would like to know
how is the progress in relation to Lock Optimistic Persistence API's
available: Mapper, Record and JPA.

I have been verified to exists the Squeryl Optimistic Lock and didn't
saw any reference to the SquerylRecord plugin. Is there any way to
implement Optimistic Lock via Lift-Record and Squeryl or other?

Example in Squeryl (http://squeryl.org/occ.html):

class Book(val id: Long,
var title: String,
var authorId: Long) extends KeyedEntity[Long] with
Optimistic


For robust applications in Lift, with data relations, optimistic lock
and others is recommended to use Lift JPA (API)?

Thanks,

Sincerely,

Roberto Silveira Beneti

David Whittaker

unread,
May 30, 2011, 12:39:41 PM5/30/11
to lif...@googlegroups.com
H Roberto,

The reason there is no reference to optimistic concurrency in the Lift Wiki is because it's no different from Squeryl without record.  Just add the org.squeryl.Optimistic trait to your entity class and you should be good.  If you have any trouble with that let me know and I'll look into it.

-Dave


--
You received this message because you are subscribed to the Google Groups "Lift" group.
To post to this group, send email to lif...@googlegroups.com.
To unsubscribe from this group, send email to liftweb+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/liftweb?hl=en.


Roberto

unread,
May 30, 2011, 1:39:51 PM5/30/11
to Lift
Hello Dave,

Thanks for answering my question.

My question is related to how use the Lock optimist with Squeryl and
Record, because if I just add the org.squeryl.Optimistic trait in my
entity class, I have/need to extend my entity class to
org.squeryl.KeyedEntity, and I didn't use Record, just squeryl,
without lift-record. Right?

So, why I use lift-record Layer?

What is better for robust application? Lift-JPA?

Thanks again.

Roberto Silveira Beneti
> >http://groups.google.com/group/liftweb?hl=en.- Ocultar texto das mensagens anteriores -
>
> - Mostrar texto das mensagens anteriores -

David Whittaker

unread,
May 30, 2011, 2:03:01 PM5/30/11
to lif...@googlegroups.com
Most Squeryl/Record entities will implement KeyedRecord, which in turn implements KeyedEntity.  It requires you to define an idField member indicating your primary key.

As for why to use any particular persistence mechanism, they each have their strengths and weaknesses.  If a type safe way to define queries that are very similar to SQL appeals to you then Squeryl might be the way to go.  Coupling Squeryl with Record adds the ability to use LiftScreen, Lift's JSON support and better integration with other Lift features.  Lift Mapper is still the most widely used persistence mechanism, among it's other strengths and JPA.... well, if you're a Java expat that might seem the most natural to you.  They can all be used to create robust applications, it's a matter of preference.

Roberto

unread,
May 30, 2011, 1:54:34 PM5/30/11
to Lift
Hi Dave,

Thanks for answering my question.

If I use org.squeryl.Optimistic in my Entity Class, I have extends
org.squeryl.KeyedEntity[Long] with org.squeryl.Optimistic, in other
words, I do not use lift-record API, just Squeryl API, right?

Why there isn't implementation for Optimistic Locking in Lift-Record?
If I want to use another library ORM's? Such MongoDB?

I think that for applications that require more complexity in entity
relationship and optimistic lock is better to use JPA Lift-library?
Right?

Thanks again.

Roberto Silveira Beneti



On 30 maio, 13:39, David Whittaker <d...@iradix.com> wrote:

Maxime Lévesque

unread,
May 30, 2011, 3:41:08 PM5/30/11
to lif...@googlegroups.com

The term "optimistic locking" is an oxymoron, since optimistic concurrency control
is an alternative to locking, i.e. there is never a lock that takes place.
Concurrency control strategies that lock are said to be pessimistic.
Like Dave said, if you want to use OCC, you need to extend Optimistic
which in turn requires that it also extends KeyedEntity.
That being said, that alone will not solve all concurrency related problems,
you have to evaluate for every transaction, what is the requirement in terms
of consistency. It might be that you can solve most cases with OCC, and
be pessimistic (use locking) for the remaining cases, this will remain
true regardless of the technology you use.
I tend to use a mix of OCC (in the majority of cases) and locking at the
DB level (select FOR UPDATE) when pessimism is needed.
(in Squeryl  yourQuery.forUpdate will do this)

Note that MongoDB and most NoSql DBs have another model of concurrency
control, lookup keywords like MVCC and "eventual consistency".

Cheers

Roberto

unread,
May 30, 2011, 3:16:46 PM5/30/11
to Lift
Sorry for the duplicated post.

Dave, do you have any example to use EntityRecord with defined an
idField primary key?

I'm having a problem trying to declare the primary key in my Entities
(do you have any example of it? and EntityRecord with Lock
Optimistic?).

Another question about lift-record with Squeryl: does it supports
composite key in a Entity?

Thanks again,

Roberto Silveira Beneti
> > >http://groups.google.com/group/liftweb?hl=en.-Ocultar texto das mensagens anteriores -
>
> > - Mostrar texto das mensagens anteriores -- Ocultar texto das mensagens anteriores -

David Whittaker

unread,
May 30, 2011, 4:08:51 PM5/30/11
to lif...@googlegroups.com

Hi Dave,

Thanks for answering my question.

If I use org.squeryl.Optimistic in my Entity Class, I have extends
org.squeryl.KeyedEntity[Long] with org.squeryl.Optimistic, in other
words, I do not use lift-record API, just Squeryl API, right?

You can use Squeryl or Squeryl/Record.  If you're using Squeryl with Record your class definition will look something like:

class MyEntity extends Record[MyEntity] with KeyedRecord[Long] with Optimistic{

  val idField = new LongField(this)

  .....

}
 

Why there isn't implementation for Optimistic Locking in Lift-Record?
If I want to use another library ORM's? Such MongoDB?


Lift record isn't a persistence mechanism itself, it is a framework for integrating persistence mechanisms with Lift.  As Max pointed out, non-SQL stores, some of which have Record implementations, have their own locking mechanisms so adding OCC at the Record level wouldn't be possible/appropriate.
 
I think that for applications that require more complexity in entity
relationship and optimistic lock is better to use JPA Lift-library?
Right?


Not in my opinion.  I have written quite a few JPA apps and in my opinion the only time it's a better solution than Squeryl is when you're writing a Java app.  As a Squeryl committer you might consider me slightly biased though :)  Once again though, it comes down to personal preference.  If type safe, sql-like queries aren't very important to you, and you don't mind a lot of annotations on your fields, JPA might be the best solution for you.  Or if Lift integration is your primary concern and you don't mind a syntax that isn't as similar to SQL as Squeryl's you might like Mapper best.  As far as the specific features you've mentioned go, Squeryl has optimistic locking similar to JPA and while relationship modeling is different in Squeryl than it is in JPA I wouldn't say it's any less powerful, you just have to think of things in more of a database centric way than the OO way that JPA encourages.  For me that's a benefit as I've always felt like the DB interaction that JPA tries to hide leads to a lot of misunderstanding and performance problems.  Again though, that's my personal opinion.  If you want to provide more detail about what you're trying to accomplish we might be able to provide more than that.

I just saw your latest message.  Please look at the wiki entry for code examples: https://www.assembla.com/spaces/liftweb/wiki/Squeryl.  Composite keys are handled just like they are in regular Squeryl, the only difference is the type parameters to CompositeKeyN are the record field types (i.e CompositeKey2[StringField[MyEntity], LongField[MyEntity]]) so they are a bit more verbose.

Roberto

unread,
May 30, 2011, 4:36:41 PM5/30/11
to Lift
Maxime and Dave, thanks a lot.

When I follow the exact example in Squery Page (OCC - http://squeryl.org/occ.html)
it's works fine.

When I try to put the Lock Optimistic in my Entity, using the Lift-
Record example, the following error occurs:

My Entity Class Book:
class Book private() extends Record[Book] with KeyedRecord[Long]
with Optimistic {
override def meta = Book
@Column(name="id")
override val idField = new LongField(this)
val publisherId = new LongField(this, 0)
val authorId = new LongField(this, 0)
val title = new StringField(this, "")
val publishedInYear = new IntField(this, 1990)
}

The following error (failed to find field occVersionNumber in Record
metadata):

Caused by: java.lang.RuntimeException: failed to find field
occVersionNumber in
Record metadata for class com.company.model.Book
at scala.Predef$.error(Predef.scala:58) ~[scala-
library-2.8.1.jar:na]
at net.liftweb.squerylrecord.RecordMetaDataFactory.fieldFrom
$1(RecordMet
aDataFactory.scala:42) ~[lift-squeryl-record_2.8.1-2.3-M1.jar:2.3-M1]
at
net.liftweb.squerylrecord.RecordMetaDataFactory.findMetaField(RecordM
etaDataFactory.scala:46) ~[lift-squeryl-record_2.8.1-2.3-M1.jar:2.3-
M1]
at
net.liftweb.squerylrecord.RecordMetaDataFactory.build(RecordMetaDataF
actory.scala:70) ~[lift-squeryl-record_2.8.1-2.3-M1.jar:2.3-M1]
at org.squeryl.internals.PosoMetaData$$anonfun
$3.apply(PosoMetaData.scal
a:111) ~[squeryl_2.8.1-0.9.4-RC3.jar:na]
at org.squeryl.internals.PosoMetaData$$anonfun
$3.apply(PosoMetaData.scal
a:80) ~[squeryl_2.8.1-0.9.4-RC3.jar:na]
at scala.collection.immutable.HashMap
$HashMap1.foreach(HashMap.scala:125
) ~[scala-library-2.8.1.jar:na]

Does anyone have any idea?

Thanks again

Roberto Silveira Beneti
> > > >http://groups.google.com/group/liftweb?hl=en.-Ocultar texto das

David Whittaker

unread,
May 30, 2011, 6:33:13 PM5/30/11
to lif...@googlegroups.com
Looks like a bug.  Let me take a closer look and get back to you.

Roberto

unread,
May 31, 2011, 8:04:33 AM5/31/11
to Lift
Thank you,

I'll wait.

Roberto Silveira Beneti
> > > > > >http://groups.google.com/group/liftweb?hl=en.-Ocultartexto das

David Whittaker

unread,
May 31, 2011, 11:56:38 AM5/31/11
to lif...@googlegroups.com
Roberto,

I've got a fix up on review board now.  I'll let you know when it's available.

David Whittaker

unread,
Jun 1, 2011, 9:38:20 AM6/1/11
to lif...@googlegroups.com
Roberto,

I put my fix into master yesterday evening.  It should be available in 2.4-SNAPSHOT by now.  Let me know if you continue to have issues.  

On Tue, May 31, 2011 at 8:04 AM, Roberto <roberto...@gmail.com> wrote:

Roberto

unread,
Jun 1, 2011, 10:07:37 AM6/1/11
to Lift
Thank you David,

I will now test the fix and will post a feedback.

Thanks again,

Roberto Silveira Beneti

> >http://groups.google.com/group/liftweb?hl=en.- Hide quoted text -
>
> - Show quoted text -

Roberto

unread,
Jun 2, 2011, 3:34:40 PM6/2/11
to Lift
Hi David,

I was downloaded the version 2.4-SNAPSHOT of LIFT and tried again
getting the same error.

It may be that because I'm not using the proper version, so I'll put
how I'm downloaded the version 2.4-SNAPSHOT with Maven:

>mvn archetype:generate -DarchetypeGroupId=net.liftweb -
DarchetypeArtifactId=lift-archetype-blank_2.8.1 -
DarchetypeVersionId=2.4-SNAPSHOT -DarchetypeRepository=http://scala-
tools.org/repo-snapshots -DremoteRepositories=http://scala-tools.org/
repo-snapshots -DgroupId=com.company -DartifactId=lift_blank

Is there any other way recommended to download the Lift 2.4-SNAPSHOT
(with fix)?

Thanks again,

Roberto Silveira Benet
> > > > - Mostrar texto das mensagens- Hide quoted text -
>
> - Show quoted text -...
>
> read more »

Derek Chen-Becker

unread,
Jun 2, 2011, 3:55:56 PM6/2/11
to lif...@googlegroups.com
Just for giggles I would try clearing your ~/.m2/repository directory to make sure it's really grabbing the latest.

Derek

David Whittaker

unread,
Jun 2, 2011, 4:19:58 PM6/2/11
to lif...@googlegroups.com
I agree with Derek.  I've got a Spec in there that applies the Optimistic trait and confirms that it throws an exception in the proper circumstances, and I'm fairly sure that the latest SNAPSHOT at scala-tools.org includes my commits.  I'd try removing the lift-squeryl-record jar from your local repo first, if that doesn't work let us know and we'll figure figure out where to go next.

Roberto

unread,
Jun 2, 2011, 7:01:19 PM6/2/11
to Lift
Dave/Derek,

Thanks very much. Now it's work (Optimistic with Lift-Record).

I really wasn't with version 2.4-SNAPSHOT in the dependencies and
plugins of my project.

I am amazed of this community.

Thanks for the answers.

Roberto Silveira Beneti

On Jun 2, 5:19 pm, David Whittaker <d...@iradix.com> wrote:
> I agree with Derek.  I've got a Spec in there that applies the Optimistic
> trait and confirms that it throws an exception in the proper circumstances,
> and I'm fairly sure that the latest SNAPSHOT at scala-tools.org includes my
> commits.  I'd try removing the lift-squeryl-record jar from your local repo
> first, if that doesn't work let us know and we'll figure figure out where to
> go next....
>
> read more »
>
> On Thu, Jun 2, 2011 at 3:55 PM, Derek Chen-Becker <dchenbec...@gmail.com>wrote:
>
>
>
> > Just for giggles I would try clearing your ~/.m2/repository directory to
> > make sure it's really grabbing the latest.
>
> > Derek
>
> > On Thu, Jun 2, 2011 at 1:34 PM, Roberto <roberto.sben...@gmail.com> wrote:
>
> >> Hi David,
>
> >> I was downloaded the version 2.4-SNAPSHOT of LIFT and tried again
> >> getting the same error.
>
> >>  It may be that because I'm not using the proper version, so I'll put
> >> how I'm downloaded the version 2.4-SNAPSHOT with Maven:
>
> >>  >mvn archetype:generate -DarchetypeGroupId=net.liftweb -
> >> DarchetypeArtifactId=lift-archetype-blank_2.8.1 -
> >> DarchetypeVersionId=2.4-SNAPSHOT -DarchetypeRepository=http://scala-
> >> tools.org/repo-snapshots -DremoteRepositories=http://scala-tools.org/
> >> repo-snapshots <http://scala-tools.org/%0Arepo-snapshots>-DgroupId=com.company -DartifactId=lift_blank
> >> > > > > > didn't- Hide quoted text -

David Pollak

unread,
Jun 2, 2011, 7:04:43 PM6/2/11
to lif...@googlegroups.com
On Thu, Jun 2, 2011 at 4:01 PM, Roberto <roberto...@gmail.com> wrote:
Dave/Derek,

Thanks very much. Now it's work (Optimistic with Lift-Record).

I really wasn't with version 2.4-SNAPSHOT in the dependencies and
plugins of my project.

I am amazed of this community.


Glad you like the responses... feel encouraged to nominate folks for the Happy Lift'r prize in this thread: https://groups.google.com/d/topic/liftweb/dCA89xrW01E/discussion
 

--
You received this message because you are subscribed to the Google Groups "Lift" group.
To post to this group, send email to lif...@googlegroups.com.
To unsubscribe from this group, send email to liftweb+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/liftweb?hl=en.




--
Lift, the simply functional web framework http://liftweb.net

Roberto

unread,
Jun 3, 2011, 7:23:53 PM6/3/11
to Lift
Hi Dave,

Continuing my testing with Optimistic Lock, I have the following
problem:

How can I make a page for editing (in web), and update the database?

If I use the partial form of persistence, It can't return error in
persistence, so Optimistic Lock didn't work:
update (Bookstore.authors) (s => where (s.idField === 1) set
(s.name: = "Roberto3" s.occVersionNumber: = 8))

If I use the full form I can't set the value of occVersionNumber,
because it is a protected val Int. Full form:
author2.name("Roberto3")
author2.idField(id)
author2.occVersionNumber = 8 (ERROR)
Bookstore.authors.update(author2)

If I use the following way works, but I just had to do a get first,
and didn't want to do this:
val author2 = Bookstore.authors.lookup(id).get
author2.name("Roberto3")
Bookstore.authors.update(author2)

Would You have any examples to show with implementation of Optimistic
Lock in an edit form on the web project?

Thanks,

Roberto Silveira Beneti

On Jun 2, 8:04 pm, David Pollak <feeder.of.the.be...@gmail.com> wrote:
> ...
>
> read more »- Hide quoted text -

David Whittaker

unread,
Jun 9, 2011, 10:23:45 AM6/9/11
to lif...@googlegroups.com
Roberto,

I saw the thread you started on the Squeryl list as well.  The typical usage scenario for this would be that you retrieve the full object when you create the form then retain the retrieved object until the form is posted back, setting it's fields from the form and calling Table.update to save to the DB.

You shouldn't ever have to set the occVersionNumber field directly.  The idea is that the retrieved object carries it around and it is tested against the value in the DB behind the scenes on each update.  That way you know if the row that defines the object has been updated since you did the retrieval.

Roberto

unread,
Jun 13, 2011, 2:31:13 PM6/13/11
to Lift
Ok,

If it is to be used this way.

Thanks again.

On 9 jun, 11:23, David Whittaker <d...@iradix.com> wrote:
> Roberto,
>
> ...
>
> mais »

David Whittaker

unread,
Jun 15, 2011, 5:30:06 PM6/15/11
to lif...@googlegroups.com
Roberto,

If that method doesn't fit the style of app you're writing feel free to elaborate and I'll see what I can come up with.

-Dave


--
Reply all
Reply to author
Forward
0 new messages