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
>>>>
>>>
[debug 2018/10/19 09:36:47.580 IST <pool-3-thread-1> tid=0x4b] Creating new
transaction with name
[com.example.geode.service.CustomerService.updateCustomer]:
PROPAGATION_REQUIRED,ISOLATION_DEFAULT
[debug 2018/10/19 09:36:47.580 IST <pool-3-thread-1> tid=0x4b] Acquired GemFire
Cache [GemFireCache[id = 1149747394; isClosing = false; isShutDownAll = false;
created = Fri Oct 19 09:36:44 IST 2018; server = false; copyOnRead = true;
lockLease = 120; lockTimeout = 60]] for local cache transaction
pool-3-thread-1 : Entered into update method
[debug 2018/10/19 09:36:47.581 IST <pool-3-thread-1> tid=0x4b] Built a new
TXState: class org.apache.geode.internal.cache.TXState@1811765862
onBehalfOfRemoteStub:false me:192.168.31.62(SampleServer:9006)<ec><v0>:1024
[debug 2018/10/19 09:36:47.581 IST <pool-3-thread-1> tid=0x4b] TXState
writeRegion flag false region-state
{org.apache.geode.internal.cache.TXRegionState@653aa969 ,entryMods={}
,isCreatedDuringCommit=false}
[debug 2018/10/19 09:36:47.586 IST <pool-3-thread-2> tid=0x4c] Creating new
transaction with name
[com.example.geode.service.CustomerService.updateCustomer]:
PROPAGATION_REQUIRED,ISOLATION_DEFAULT
[debug 2018/10/19 09:36:47.586 IST <pool-3-thread-2> tid=0x4c] Acquired GemFire
Cache [GemFireCache[id = 1149747394; isClosing = false; isShutDownAll = false;
created = Fri Oct 19 09:36:44 IST 2018; server = false; copyOnRead = true;
lockLease = 120; lockTimeout = 60]] for local cache transaction
pool-3-thread-2 : Entered into update method
[debug 2018/10/19 09:36:47.587 IST <pool-3-thread-2> tid=0x4c] Built a new
TXState: class org.apache.geode.internal.cache.TXState@1585159213
onBehalfOfRemoteStub:false me:192.168.31.62(SampleServer:9006)<ec><v0>:1024
[debug 2018/10/19 09:36:47.587 IST <pool-3-thread-2> tid=0x4c] TXState
writeRegion flag false region-state
{org.apache.geode.internal.cache.TXRegionState@50bc7992 ,entryMods={}
,isCreatedDuringCommit=false}
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-1 : Current customer name >> A1
pool-3-thread-2 : Current customer name >> A1
pool-3-thread-1 : Final Data >> {
"cid" : "1234",
"name" : "A2",
"address" : "India"
}
pool-3-thread-2 : Final Data >> {
"cid" : "1234",
"name" : "A3",
"address" : "India"
}
pool-3-thread-2 : Exiting from update method
pool-3-thread-1 : Exiting from update method
[debug 2018/10/19 09:36:48.606 IST <pool-3-thread-1> tid=0x4b] Initiating
transaction commit
[debug 2018/10/19 09:36:48.606 IST <pool-3-thread-2> tid=0x4c] Initiating
transaction commit
[debug 2018/10/19 09:36:48.607 IST <pool-3-thread-1> tid=0x4b] Committing local
cache transaction
[debug 2018/10/19 09:36:48.607 IST <pool-3-thread-2> tid=0x4c] Committing local
cache transaction
[debug 2018/10/19 09:36:48.607 IST <pool-3-thread-1> tid=0x4b] committing
transaction TXId: 192.168.31.62(SampleServer:9006)<ec><v0>:1024:4
[debug 2018/10/19 09:36:48.607 IST <pool-3-thread-2> tid=0x4c] committing
transaction TXId: 192.168.31.62(SampleServer:9006)<ec><v0>:1024:5
[debug 2018/10/19 09:36:48.607 IST <pool-3-thread-2> tid=0x4c]
TXRegionState.createLockRequest 1 DistributedRegion
region-state={org.apache.geode.internal.cache.TXRegionState@50bc7992
,entryMods={1234={org.apache.geode.internal.cache.TXEntryState@3f084aae 23}}
,isCreatedDuringCommit=false}
[debug 2018/10/19 09:36:48.607 IST <pool-3-thread-1> tid=0x4b]
TXRegionState.createLockRequest 1 DistributedRegion
region-state={org.apache.geode.internal.cache.TXRegionState@653aa969
,entryMods={1234={org.apache.geode.internal.cache.TXEntryState@35d29ab5 23}}
,isCreatedDuringCommit=false}
[debug 2018/10/19 09:36:48.607 IST <pool-3-thread-2> tid=0x4c]
TXRegionState.createLockRequest 2
[debug 2018/10/19 09:36:48.607 IST <pool-3-thread-1> tid=0x4b]
TXRegionState.createLockRequest 2
[debug 2018/10/19 09:36:48.607 IST <pool-3-thread-1> tid=0x4b]
[TXLockServiceImpl.txLock] acquire try-locks for [TXLockBatch:
txLockId=TXLockId: 192.168.31.62(SampleServer:9006)<ec><v0>:1024-4;
reqs=[regionPath=/Customers keys=[1234]]; participants=[]]
[debug 2018/10/19 09:36:48.607 IST <pool-3-thread-2> tid=0x4c]
[TXLockServiceImpl.txLock] acquire try-locks for [TXLockBatch:
txLockId=TXLockId: 192.168.31.62(SampleServer:9006)<ec><v0>:1024-3;
reqs=[regionPath=/Customers keys=[1234]]; participants=[]]
[debug 2018/10/19 09:36:48.608 IST <pool-3-thread-1> tid=0x4b]
<DLockRequestProcessor 14 waiting for 1 replies from
[192.168.31.62(SampleServer:9006)<ec><v0>:1024]> got
process(DLockRequestProcessor.DLockResponseMessage responding GRANT;
serviceName=DTLS(version 4); objectName=[TXLockBatch: txLockId=TXLockId:
192.168.31.62(SampleServer:9006)<ec><v0>:1024-4; reqs=[regionPath=/Customers
keys=[1234]]; participants=[]]; responseCode=0; keyIfFailed=null;
leaseExpireTime=9223372036854775807; processorId=14; lockId=14) from
192.168.31.62(SampleServer:9006)<ec><v0>:1024
[debug 2018/10/19 09:36:48.608 IST <pool-3-thread-1> tid=0x4b]
[TXLockServiceImpl.txLock] gotLocks is true, returning txLockId:TXLockId:
192.168.31.62(SampleServer:9006)<ec><v0>:1024-4
[debug 2018/10/19 09:36:48.608 IST <pool-3-thread-1> tid=0x4b]
generateEventOffsets() entries
[org.apache.geode.internal.cache.TXState$TXEntryStateWithRegionAndKey@1]
RegionState
Map={org.apache.geode.internal.cache.DistributedRegion[path='/Customers';scope=DISTRIBUTED_ACK';dataPolicy=REPLICATE;
concurrencyChecksEnabled]={org.apache.geode.internal.cache.TXRegionState@653aa969
,entryMods={1234={org.apache.geode.internal.cache.TXEntryState@35d29ab5 23}}
,isCreatedDuringCommit=false}}
[debug 2018/10/19 09:36:48.608 IST <pool-3-thread-1> tid=0x4b] applyChanges
txState=class org.apache.geode.internal.cache.TXState@1811765862
onBehalfOfRemoteStub:false ,key=1234 ,r=Customers ,op=23 ,isDirty=true
[debug 2018/10/19 09:36:48.608 IST <pool-3-thread-1> tid=0x4b] txApplyPut
cbEvent=EntryEventImpl[op=UPDATE;region=/Customers;key=1234;oldValue=null;newValue=com.example.geode.model.Customer@3491dea3;callbackArg=null;originRemote=false;originMember=192.168.31.62(SampleServer:9006)<ec><v0>:1024;id=EventIDid=30bytes;threadID=3;sequenceID=1]]
[debug 2018/10/19 09:36:48.609 IST <pool-3-thread-2> tid=0x4c]
<DLockRequestProcessor 13 waiting for 1 replies from
[192.168.31.62(SampleServer:9006)<ec><v0>:1024]> got
process(DLockRequestProcessor.DLockResponseMessage responding TRY_LOCK_FAILED;
serviceName=DTLS(version 0); objectName=[TXLockBatch: txLockId=TXLockId:
192.168.31.62(SampleServer:9006)<ec><v0>:1024-3; reqs=[regionPath=/Customers
keys=[1234]]; participants=[]]; responseCode=4; keyIfFailed=The key 1234 in
region /Customers was being modified by another transaction locally.;
leaseExpireTime=0; processorId=13; lockId=13) from
192.168.31.62(SampleServer:9006)<ec><v0>:1024
[debug 2018/10/19 09:36:48.609 IST <pool-3-thread-1> tid=0x4b] generated tag
{v2; rv2; time=1539922008609}; key=1234;
oldvalue=com.example.geode.model.Customer@7944b8b4
newvalue=com.example.geode.model.Customer@3491dea3 client=none
region=/Customers; rvv=RegionVersionVector{rv2 gc0}@766445308
[debug 2018/10/19 09:36:48.609 IST <pool-3-thread-1> tid=0x4b] generated
version tag {v2; rv2; time=1539922008609} for 1234
[debug 2018/10/19 09:36:48.609 IST <pool-3-thread-1> tid=0x4b] empty
transaction - nothing to distribute
[debug 2018/10/19 09:36:48.609 IST <pool-3-thread-1> tid=0x4b]
invokeTXCallbacks for event
EntryEventImpl[op=UPDATE;region=/Customers;key=1234;oldValue=com.example.geode.model.Customer@7944b8b4;newValue=com.example.geode.model.Customer@3491dea3;callbackArg=null;originRemote=false;originMember=192.168.31.62(SampleServer:9006)<ec><v0>:1024;version={v2;
rv2; time=1539922008609};id=EventIDid=30bytes;threadID=3;sequenceID=1]]