google-code-export / morphia

Automatically exported from code.google.com/p/morphia
1 stars 0 forks source link

Optimistic Locking not working? #345

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
Please note the output from the unit test below,
Thread2 Sam D version null
Thread2 Booked
Thread3 Jenny B version null
Thread3 Booked

I expect 2 threads to get Booked and 2 to fail with "No available slots"

I am expecting exception to be thrown for Thread3, because Thread2 got in first 
so version should have been updated, ie. no longer null. 

What version are you using? (Morphia 0.99/Driver 2.7.2/MongoDB 
mongodb-win32-i386-2.0.0)

Please include a stack trace below:
[INFO] Scanning for projects...
[WARNING] 
[WARNING] Some problems were encountered while building the effective model for 
org.springframework.samples.spring:morphia-optimistic-locking:jar:1.0.0.CI-SNAPS
HOT
[WARNING] 'build.plugins.plugin.version' for 
org.apache.maven.plugins:maven-compiler-plugin is missing. @ line 98, column 12
[WARNING] 
[WARNING] It is highly recommended to fix these problems because they threaten 
the stability of your build.
[WARNING] 
[WARNING] For this reason, future Maven versions might no longer support 
building such malformed projects.
[WARNING] 
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building MorphiaOptimisticLocking 1.0.0.CI-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-resources-plugin:2.4.3:resources (default-resources) @ 
morphia-optimistic-locking ---
[WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, 
i.e. build is platform dependent!
[INFO] Copying 1 resource
[INFO] 
[INFO] --- maven-compiler-plugin:2.3.2:compile (default-compile) @ 
morphia-optimistic-locking ---
[WARNING] File encoding has not been set, using platform encoding Cp1252, i.e. 
build is platform dependent!
[INFO] Compiling 6 source files to 
C:\dev\workspace-sts-2.7.1.RELEASE\MorphiaOptimisticLocking\target\classes
[INFO] 
[INFO] --- maven-resources-plugin:2.4.3:testResources (default-testResources) @ 
morphia-optimistic-locking ---
[WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, 
i.e. build is platform dependent!
[INFO] Copying 1 resource
[INFO] 
[INFO] --- maven-compiler-plugin:2.3.2:testCompile (default-testCompile) @ 
morphia-optimistic-locking ---
[WARNING] File encoding has not been set, using platform encoding Cp1252, i.e. 
build is platform dependent!
[INFO] Compiling 3 source files to 
C:\dev\workspace-sts-2.7.1.RELEASE\MorphiaOptimisticLocking\target\test-classes
[INFO] 
[INFO] --- maven-surefire-plugin:2.7.2:test (default-test) @ 
morphia-optimistic-locking ---
[INFO] Surefire report directory: 
C:\dev\workspace-sts-2.7.1.RELEASE\MorphiaOptimisticLocking\target\surefire-repo
rts

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running au.com.iselect.calendar.ExampleServiceTest
[10:28:53] ExampleServiceTest-1-thread-3 INFO  logging.MorphiaLoggerFactory  - 
LoggerImplFactory set to 
com.google.code.morphia.logging.slf4j.SLF4JLogrImplFactory
[10:28:53] ExampleServiceTest-1-thread-3 DEBUG calendar.ExampleServiceTest  - 
starting ...
[10:28:53] ExampleServiceTest-1-thread-4 DEBUG service.BookingDetailService  - 
loadOrCreate attempt: 0 another user beat us to it.
com.mongodb.MongoException$DuplicateKey: E11000 duplicate key error index: 
cal_dev.BookingDetail.$_id_  dup key: { : "24-11-2011" }
    at com.mongodb.CommandResult.getException(CommandResult.java:85)
    at com.mongodb.CommandResult.throwOnError(CommandResult.java:121)
    at com.mongodb.DBTCPConnector._checkWriteError(DBTCPConnector.java:131)
    at com.mongodb.DBTCPConnector.say(DBTCPConnector.java:155)
    at com.mongodb.DBTCPConnector.say(DBTCPConnector.java:138)
    at com.mongodb.DBApiLayer$MyCollection.insert(DBApiLayer.java:261)
    at com.mongodb.DBApiLayer$MyCollection.insert(DBApiLayer.java:211)
    at com.mongodb.DBCollection.insert(DBCollection.java:57)
    at com.mongodb.DBCollection.insert(DBCollection.java:87)
    at com.google.code.morphia.DatastoreImpl.insert(DatastoreImpl.java:664)
    at com.google.code.morphia.DatastoreImpl.insert(DatastoreImpl.java:642)
    at com.google.code.morphia.DatastoreImpl.insert(DatastoreImpl.java:637)
    at au.com.iselect.calendar.service.BookingDetailService.create(BookingDetailService.java:84)
    at au.com.iselect.calendar.service.BookingDetailService.loadOrCreate(BookingDetailService.java:44)
    at au.com.iselect.calendar.service.BookingDetailService.book(BookingDetailService.java:123)
    at au.com.iselect.calendar.ExampleServiceTest.test4(ExampleServiceTest.java:80)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:619)
[10:28:53] ExampleServiceTest-1-thread-2 DEBUG service.BookingDetailService  - 
Book for customer: Sam D version: null ...
[10:28:53] ExampleServiceTest-1-thread-3 DEBUG service.BookingDetailService  - 
loadOrCreate attempt: 0 another user beat us to it.
com.mongodb.MongoException$DuplicateKey: E11000 duplicate key error index: 
cal_dev.BookingDetail.$_id_  dup key: { : "24-11-2011" }
    at com.mongodb.CommandResult.getException(CommandResult.java:85)
    at com.mongodb.CommandResult.throwOnError(CommandResult.java:121)
    at com.mongodb.DBTCPConnector._checkWriteError(DBTCPConnector.java:131)
    at com.mongodb.DBTCPConnector.say(DBTCPConnector.java:155)
    at com.mongodb.DBTCPConnector.say(DBTCPConnector.java:138)
    at com.mongodb.DBApiLayer$MyCollection.insert(DBApiLayer.java:261)
    at com.mongodb.DBApiLayer$MyCollection.insert(DBApiLayer.java:211)
    at com.mongodb.DBCollection.insert(DBCollection.java:57)
    at com.mongodb.DBCollection.insert(DBCollection.java:87)
    at com.google.code.morphia.DatastoreImpl.insert(DatastoreImpl.java:664)
    at com.google.code.morphia.DatastoreImpl.insert(DatastoreImpl.java:642)
    at com.google.code.morphia.DatastoreImpl.insert(DatastoreImpl.java:637)
    at au.com.iselect.calendar.service.BookingDetailService.create(BookingDetailService.java:84)
    at au.com.iselect.calendar.service.BookingDetailService.loadOrCreate(BookingDetailService.java:44)
    at au.com.iselect.calendar.service.BookingDetailService.book(BookingDetailService.java:123)
    at au.com.iselect.calendar.ExampleServiceTest.test3(ExampleServiceTest.java:69)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:619)
[10:28:53] ExampleServiceTest-1-thread-1 DEBUG service.BookingDetailService  - 
loadOrCreate attempt: 0 another user beat us to it.
com.mongodb.MongoException$DuplicateKey: E11000 duplicate key error index: 
cal_dev.BookingDetail.$_id_  dup key: { : "24-11-2011" }
    at com.mongodb.CommandResult.getException(CommandResult.java:85)
    at com.mongodb.CommandResult.throwOnError(CommandResult.java:121)
    at com.mongodb.DBTCPConnector._checkWriteError(DBTCPConnector.java:131)
    at com.mongodb.DBTCPConnector.say(DBTCPConnector.java:155)
    at com.mongodb.DBTCPConnector.say(DBTCPConnector.java:138)
    at com.mongodb.DBApiLayer$MyCollection.insert(DBApiLayer.java:261)
    at com.mongodb.DBApiLayer$MyCollection.insert(DBApiLayer.java:211)
    at com.mongodb.DBCollection.insert(DBCollection.java:57)
    at com.mongodb.DBCollection.insert(DBCollection.java:87)
    at com.google.code.morphia.DatastoreImpl.insert(DatastoreImpl.java:664)
    at com.google.code.morphia.DatastoreImpl.insert(DatastoreImpl.java:642)
    at com.google.code.morphia.DatastoreImpl.insert(DatastoreImpl.java:637)
    at au.com.iselect.calendar.service.BookingDetailService.create(BookingDetailService.java:84)
    at au.com.iselect.calendar.service.BookingDetailService.loadOrCreate(BookingDetailService.java:44)
    at au.com.iselect.calendar.service.BookingDetailService.book(BookingDetailService.java:123)
    at au.com.iselect.calendar.ExampleServiceTest.test1(ExampleServiceTest.java:47)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:619)
[10:28:53] ExampleServiceTest-1-thread-2 DEBUG service.BookingDetailService  - 
Booked.
[10:28:53] ExampleServiceTest-1-thread-3 DEBUG service.BookingDetailService  - 
Book for customer: Jenny B version: null ...
[10:28:53] ExampleServiceTest-1-thread-4 DEBUG service.BookingDetailService  - 
Book for customer: Janet T version: 1322436533153 ...
[10:28:53] ExampleServiceTest-1-thread-1 DEBUG service.BookingDetailService  - 
Book for customer: Jill P version: 1322436533153 ...
[10:28:53] ExampleServiceTest-1-thread-3 DEBUG service.BookingDetailService  - 
Booked.
[10:28:53] ExampleServiceTest-1-thread-1 DEBUG service.BookingDetailService  - 
Book attempt: 0 failed, another user beat us to it.
java.util.ConcurrentModificationException: Entity of class 
au.com.iselect.calendar.domain.BookingDetail 
(id='24-11-2011',version='1322436533153') was concurrently updated.
    at com.google.code.morphia.DatastoreImpl.tryVersionedUpdate(DatastoreImpl.java:760)
    at com.google.code.morphia.DatastoreImpl.save(DatastoreImpl.java:725)
    at com.google.code.morphia.DatastoreImpl.save(DatastoreImpl.java:793)
    at com.google.code.morphia.DatastoreImpl.save(DatastoreImpl.java:787)
    at au.com.iselect.calendar.service.BookingDetailService.update(BookingDetailService.java:110)
    at au.com.iselect.calendar.service.BookingDetailService.book(BookingDetailService.java:142)
    at au.com.iselect.calendar.ExampleServiceTest.test1(ExampleServiceTest.java:47)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:619)
[10:28:53] ExampleServiceTest-1-thread-4 DEBUG service.BookingDetailService  - 
Book attempt: 0 failed, another user beat us to it.
java.util.ConcurrentModificationException: Entity of class 
au.com.iselect.calendar.domain.BookingDetail 
(id='24-11-2011',version='1322436533153') was concurrently updated.
    at com.google.code.morphia.DatastoreImpl.tryVersionedUpdate(DatastoreImpl.java:760)
    at com.google.code.morphia.DatastoreImpl.save(DatastoreImpl.java:725)
    at com.google.code.morphia.DatastoreImpl.save(DatastoreImpl.java:793)
    at com.google.code.morphia.DatastoreImpl.save(DatastoreImpl.java:787)
    at au.com.iselect.calendar.service.BookingDetailService.update(BookingDetailService.java:110)
    at au.com.iselect.calendar.service.BookingDetailService.book(BookingDetailService.java:142)
    at au.com.iselect.calendar.ExampleServiceTest.test4(ExampleServiceTest.java:80)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:619)
[10:28:53] ExampleServiceTest-1-thread-1 DEBUG service.BookingDetailService  - 
Book for customer: Jill P version: 1322436533155 ...
[10:28:53] ExampleServiceTest-1-thread-4 DEBUG service.BookingDetailService  - 
Book for customer: Janet T version: 1322436533155 ...
[10:28:53] ExampleServiceTest-1-thread-1 DEBUG service.BookingDetailService  - 
Booked.
[10:28:53] ExampleServiceTest-1-thread-4 DEBUG service.BookingDetailService  - 
Book attempt: 1 failed, another user beat us to it.
java.util.ConcurrentModificationException: Entity of class 
au.com.iselect.calendar.domain.BookingDetail 
(id='24-11-2011',version='1322436533155') was concurrently updated.
    at com.google.code.morphia.DatastoreImpl.tryVersionedUpdate(DatastoreImpl.java:760)
    at com.google.code.morphia.DatastoreImpl.save(DatastoreImpl.java:725)
    at com.google.code.morphia.DatastoreImpl.save(DatastoreImpl.java:793)
    at com.google.code.morphia.DatastoreImpl.save(DatastoreImpl.java:787)
    at au.com.iselect.calendar.service.BookingDetailService.update(BookingDetailService.java:110)
    at au.com.iselect.calendar.service.BookingDetailService.book(BookingDetailService.java:142)
    at au.com.iselect.calendar.ExampleServiceTest.test4(ExampleServiceTest.java:80)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:619)
Tests run: 4, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.293 sec <<< 
FAILURE!

Results :

Tests in error: 
  test4(au.com.iselect.calendar.ExampleServiceTest): No available slots for xxx

Tests run: 4, Failures: 0, Errors: 1, Skipped: 0

[ERROR] There are test failures.

Please refer to 
C:\dev\workspace-sts-2.7.1.RELEASE\MorphiaOptimisticLocking\target\surefire-repo
rts for the individual test results.
[INFO] 
[INFO] --- maven-jar-plugin:2.3.1:jar (default-jar) @ 
morphia-optimistic-locking ---
[INFO] Building jar: 
C:\dev\workspace-sts-2.7.1.RELEASE\MorphiaOptimisticLocking\target\morphia-optim
istic-locking-1.0.0.CI-SNAPSHOT.jar
[INFO] 
[INFO] --- maven-install-plugin:2.3.1:install (default-install) @ 
morphia-optimistic-locking ---
[INFO] Installing 
C:\dev\workspace-sts-2.7.1.RELEASE\MorphiaOptimisticLocking\target\morphia-optim
istic-locking-1.0.0.CI-SNAPSHOT.jar to 
C:\Users\srowe\.m2\repository\org\springframework\samples\spring\morphia-optimis
tic-locking\1.0.0.CI-SNAPSHOT\morphia-optimistic-locking-1.0.0.CI-SNAPSHOT.jar
[INFO] Installing 
C:\dev\workspace-sts-2.7.1.RELEASE\MorphiaOptimisticLocking\pom.xml to 
C:\Users\srowe\.m2\repository\org\springframework\samples\spring\morphia-optimis
tic-locking\1.0.0.CI-SNAPSHOT\morphia-optimistic-locking-1.0.0.CI-SNAPSHOT.pom
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.965s
[INFO] Finished at: Mon Nov 28 10:28:53 EST 2011
[INFO] Final Memory: 10M/24M
[INFO] ------------------------------------------------------------------------

Original issue reported on code.google.com by seb_r...@hotmail.com on 27 Nov 2011 at 11:50

Attachments:

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
I haven't looked at your test code yet, but are you sharing the same 
Entity/objects in multiple threads and updating it multiple times? That check 
is per instance of the entity. 

If you are saving it from multiple threads without synchronizing the 
access/persistence in your java code that is not safe ind. of Morphia.

Original comment by scotthernandez on 28 Nov 2011 at 4:20

GoogleCodeExporter commented 9 years ago
Each thread does the following,
Fetch object
update object
persist object

Imagine a web app where many uses are working on the same data, this is a 
typical use case.

I suspect the problem is in the DataStoreImpl, tryVersionedUpdate method.
If it is a newly persisted object, and multiple threads trying to update the 
object get past the check on line 789, they will simply overwrite the previous 
change.

if (oldVersion != null && oldVersion > 0) {

Perhaps on persisting an object Morphia should initialise the version to 
something other than zero or null.

Original comment by seb_r...@hotmail.com on 28 Nov 2011 at 4:26

GoogleCodeExporter commented 9 years ago
Synchronizing the code is not a viable option the performance impact would be 
too great. I have programmed hibernate before with optimistic locking and there 
is no need to synchronize methods in the data access tier. The optimistic 
concurrency algorithm is supposed to check if there is a newer version in the 
database, if so then throw StaleObjectException or equivalent, so we can tell 
the user that they are working with stale data.

Original comment by seb_r...@hotmail.com on 28 Nov 2011 at 6:25