Hello Swapil & Team, Did you get chance to look into this? Ideally it's a plain case of *optimistic locking*. It works exactly fine with *JPA using @Version* property and *optimistic locking*. [Same example by changing Customer model to be compatible with database table]
As I mentioned that *both transactions are working exactly together* reading first cut copy of Customer and still passing. I believe in geode, we already have optimistic locking implemented in transactions. Could you validate debug logs and/or POC project which I had send earlier? It's similar to below customer bank account analogy I have account with bank balance as 0 initially. Tx1: When I started, customer balance was 0, so let me add $500 and end result will be $500 Tx2: When I started, customer balance was 0, so let me add $100 and end result will be $100 . Both transactions start at the same time, they read customer account object from cache, with balance as 0 initially which is nothing but a snapshot copy when transaction started. But at least 1 of the transaction should be proved wrong while committing. That's not case here and it's becoming $100. *Note*: 1 second of delay which I introduced to simulate this scenario in my poc project is just to simulate external service call which makes sense for real life project. Thanks, - Dharam Thacker On Fri, Oct 19, 2018 at 9:45 AM Dharam Thacker <[email protected]> wrote: > Thank you Swapnil! I understand your point. If I start threads as you > mentioned it does work. > > But if you see my attachment, both transactions *actually start together > with thread pool and reads same copy of customer from cache* as I have > added 1 second of delay in update service as soon as they read the copy of > customer from cache. > > I have attached *DEBUG level logs* *in file(Debug_Logs.txt)* as well more > information. I am sure something is not right here. > > After that I was expecting 1 transaction to win as other thread has > definitely older copy of customer data. Info logs shown below for quick > information. > > *INFO Logs for quick glance:* > > pool-3-thread-2 : Entered into update method > pool-3-thread-1 : Entered into update method > pool-3-thread-2 : CurrentCopy >> { > "cid" : "1234", > *"name" : "A1",* > "address" : "India" > } > pool-3-thread-1 : CurrentCopy >> { > "cid" : "1234", > *"name" : "A1",* > "address" : "India" > } > pool-3-thread-2 : Current customer name >> A1 > pool-3-thread-1 : Current customer name >> A1 > pool-3-thread-2 : Final Data >> { > "cid" : "1234", > "name" : "A3", > "address" : "India" > } > pool-3-thread-1 : Final Data >> { > "cid" : "1234", > "name" : "A2", > "address" : "India" > } > pool-3-thread-1 : Exiting from update method > pool-3-thread-2 : Exiting from update method > Main thread is going to wait for 5 seconds... > Main thread is going to shutdown pool... > > > Thanks, > Dharam > > > > On Fri, Oct 19, 2018, 03:25 Swapnil Bawaskar <[email protected]> wrote: > >> Hi Dharam, >> If there are two requests that read and write the same entry, you can >> trust Geode to throw a CommitConflictException if the changes are going to >> overwrite one another. My above example will throw this exception. >> If that exception is not thrown, then your transactions actually happened >> one after the other, in which case the second transaction should be able to >> read the change made by the first transaction. >> >> >> On Thu, Oct 18, 2018 at 11:30 AM Dharam Thacker < >> [email protected]> wrote: >> >>> Thank you Swapnil! >>> >>> But how can we guarantee this? >>> >>> I have a spring boot geode client as web app. It has several emdpoints >>> to accept add/update/delete actions. >>> >>> If 2 users are trying to change same customer with undefined email as >>> initial state in 2 different rest requests in almost same time, of course >>> by reading original customer with no email and changing emails, how could >>> this be ensured? >>> >>> It may happen that user1's transaction succeded due to many possible >>> reasons, it's confirmed now that user2 has stale data and he will overwtite >>> changes. >>> >>> Could you suggest how we can handle it? >>> >>> Thanks, >>> Dharam >>> >>> On Thu, Oct 18, 2018, 23:46 Swapnil Bawaskar <[email protected]> >>> wrote: >>> >>>> If you just throw two transactions in a thread pool, you may or may not >>>> get an exception since one transaction may have completed before the other >>>> transaction begins. To deterministically make one transaction fail, you >>>> have to ensure that both threads have read the initial value and have made >>>> change to the original value before either transaction commits. >>>> >>>> region.put("K", "V"); >>>> >>>> CountDownLatch latch1 = new CountDownLatch(1); >>>> CountDownLatch latch2 = new CountDownLatch(1); >>>> Thread th1 = new Thread(() -> { >>>> mgr.being(); >>>> region.put("K", "V1"); >>>> latch1.countDown(); >>>> latch2.await(); >>>> mgr.commit(); >>>> >>>> }); >>>> Thread th2 = new Thread(() -> { >>>> mgr.begin(); >>>> region.put("K", "V2"); >>>> latch1.await(); >>>> latch2.countDown(); >>>> mgr.commit(); >>>> }); >>>> th1.start(); >>>> th2.start(); >>>> >>>> >>>> On Thu, Oct 18, 2018 at 10:28 AM Dharam Thacker < >>>> [email protected]> wrote: >>>> >>>>> Hello Team, >>>>> >>>>> I am trying to understand *transaction behavior* with apache geode. I >>>>> have created a simple demo as attached here in with this email. >>>>> It's a simple spring data geode application with apache geode 1.6.0 >>>>> >>>>> Spring Startup Listener class >> SimpleApplicationListener .java >>>>> Service class >> CustomerService.java >>>>> >>>>> 2 thread are simultaneously trying to update customer=1234 by changing >>>>> name from [Thread-T1 - (From A1->To A2)] and [Thread-T2 - (From A1->To >>>>> A3)] >>>>> I assume that at least 1 thread has stale copy of data and should >>>>> throw commit conflict exception but I think I am missing something and >>>>> it's >>>>> not behaving as expected. >>>>> >>>>> Could some one help me to understand what I am missing here? >>>>> [Attached tar.gz file] >>>>> >>>>> Thanks & Regards, >>>>> - Dharam Thacker >>>>> >>>>
