Re: ?? about opportunistic locking...
Re: ?? about opportunistic locking...
- Subject: Re: ?? about opportunistic locking...
- From: Miguel Arroz <email@hidden>
- Date: Tue, 18 May 2010 14:07:02 +0100
Hi!
I see the point of your solution (doing whatever has to be done as soon as possible), but like Mike, I believe it has many problems:
1) Your delegate works for situations where different attributes of the same object are modified by different threads. You merge the changes made by the first thread into the second thread EC, and when you finally save, you have the object with all the changes applied. But what about the situation where both threads changed the same attribute? On the example I sent you some days ago, the attribute is a sort-of counter, so the final value depends on the initial one. If you ignore the changes made by other threads, you will be corrupting your logic. You need to be notified in the most catastrophic way possible that you WILL corrupt data if you save. Of course, you could write a specific delegate for that, but...
2) ... as said, your delegate can not throw an exception in the correct thread, which would be the best way to tell you to stop whatever you are doing and start all over again. So I add my voice to Mike's and I ask again, how can you make the second thread be notified of the problem? :)
3) You *still* have to deal with inter-instances OL exceptions, and write code for that. Why write two pieces of code in different places to do the same thing? :)
4) All this depends a lot on what you are trying to do. In Survs, for instance, there are some situations where we read a lot of objects, process them, and save them. This has to be done with all the possible guarantees that no other thread or instance is modifying the same values. The logic is so complex that I simply don't care about dealing "gracefully" with this. If it fails, I throw it all away and try to do everything again. So, I still would need that exception, or any other mechanism that prevented me from saving (and, by consequence, corrupting) my data.
5) Even if the delegate has some way of throwing the exception in the correct thread, you would have to be ready to catch that exception during the whole EC's existence and not only during the saving. That would lead to more complex code and error handling.
And, BTW, another detail for the most curious readers...
>> Application.Application: C1 1274149686265
>> Application.Application: C2 1274149686265
If this attribute was an integer or long (with the timestamp, for instance) and not a string, in this specific situation, the second commit would not produce any SQL statement. Why? :)
Yours
Miguel Arroz
On 2010/05/18, at 03:33, Mark Ritchie wrote:
> Hey Mike!
>
> On 17/May/2010, at 4:24 PM, Mike Schrag wrote:
>> so here's your challenge ... make this fail with an optimistic lock exception when EC2 saves (which is what would happen if EC1 was in another instance):
>
> But that's the point... When an EO in your application changes, you are notified via the delegate! You don't have to wait until you try to saveChanges and get the exception. I agree with what others have posted recently on this topic, getting notified of a collision at the earliest point is much preferred!
>
> As to the rest of it, I think that you're making it way too complicated...
> My delegate works just fine at caching the changes and applying them later:
> <MarksDelegate.java>
>
> This is what I've used in the past (since ObjC days) and I don't know of a case where it fails.
> M.
>
> P.S. My run log looks like this (after the 100 objects are created):
>
>
> May 17 19:28:06 UseTheDelegate[49584] DEBUG NSLog - evaluateExpression: <com.webobjects.jdbcadaptor.MySQLPlugIn$MySQLExpression: "SELECT t0.id, RTRIM(t0.name) FROM Company t0" withBindings: >
> May 17 19:28:06 UseTheDelegate[49584] DEBUG NSLog - 100 row(s) processed
> May 17 19:28:06 UseTheDelegate[49584] DEBUG NSLog - === Commit Internal Transaction
> Application.Application: ec0 = er.extensions.eof.ERXEC@7fd88db7
> Application.Application: ec1 = er.extensions.eof.ERXEC@524c71d2
> Application.Application: ec2 = er.extensions.eof.ERXEC@49198ff2
> Application.Application: Company 98
> Application.Application: Company 98
> Application.Application: Company 98
>
> C1 updated, not saved.
> Application.Application: Company 98
> Application.Application: C1 1274149686265
> Application.Application: Company 98
>
> C2 updated, not saved.
> Application.Application: Company 98
> Application.Application: C1 1274149686265
> Application.Application: C2 1274149686265
>
> May 17 19:28:06 UseTheDelegate[49584] DEBUG NSLog - === Begin Internal Transaction
> May 17 19:28:06 UseTheDelegate[49584] DEBUG NSLog - evaluateExpression: <com.webobjects.jdbcadaptor.MySQLPlugIn$MySQLExpression: "UPDATE Company SET name = ? WHERE (id = ? AND name = ?)" withBindings: 1:"C1 1274149686265"(name), 2:89(id), 3:"Company 98"(name)>
> May 17 19:28:06 UseTheDelegate[49584] DEBUG NSLog - === Commit Internal Transaction
> MarksDelegate.editingContext: er.extensions.eof.ERXEC@49198ff2 shouldMergeChangesForObject: eo = <your.app.eo.Company 2d397e5c _EOIntegralKeyGlobalID[Company (java.lang.Integer)89]>
> MarksDelegate.editingContext: er.extensions.eof.ERXEC@49198ff2 didMergeChanges:
> MarksDelegate.editingContext: er.extensions.eof.ERXEC@7fd88db7 shouldInvalidateObject: eo = <your.app.eo.Company 51701bdc _EOIntegralKeyGlobalID[Company (java.lang.Integer)89]>
> MarksDelegate.editingContext: er.extensions.eof.ERXEC@7fd88db7 didMergeChanges:
> MarksDelegate.editingContext: er.extensions.eof.ERXEC@524c71d2 shouldInvalidateObject: eo = <your.app.eo.Company 1c2006a0 _EOIntegralKeyGlobalID[Company (java.lang.Integer)89]>
> MarksDelegate.editingContext: er.extensions.eof.ERXEC@524c71d2 didMergeChanges:
> C1 saved.
> Application.Application: C1 1274149686265
> Application.Application: C1 1274149686265
> Application.Application: C2 1274149686265
>
> May 17 19:28:06 UseTheDelegate[49584] DEBUG NSLog - === Begin Internal Transaction
> May 17 19:28:06 UseTheDelegate[49584] DEBUG NSLog - evaluateExpression: <com.webobjects.jdbcadaptor.MySQLPlugIn$MySQLExpression: "UPDATE Company SET name = ? WHERE (id = ? AND name = ?)" withBindings: 1:"C2 1274149686265"(name), 2:89(id), 3:"C1 1274149686265"(name)>
> May 17 19:28:06 UseTheDelegate[49584] DEBUG NSLog - === Commit Internal Transaction
> MarksDelegate.editingContext: er.extensions.eof.ERXEC@524c71d2 shouldInvalidateObject: eo = <your.app.eo.Company 1c2006a0 _EOIntegralKeyGlobalID[Company (java.lang.Integer)89]>
> MarksDelegate.editingContext: er.extensions.eof.ERXEC@524c71d2 didMergeChanges:
> MarksDelegate.editingContext: er.extensions.eof.ERXEC@7fd88db7 shouldInvalidateObject: eo = <your.app.eo.Company 51701bdc _EOIntegralKeyGlobalID[Company (java.lang.Integer)89]>
> MarksDelegate.editingContext: er.extensions.eof.ERXEC@7fd88db7 didMergeChanges:
> MarksDelegate.editingContext: er.extensions.eof.ERXEC@49198ff2 shouldInvalidateObject: eo = <your.app.eo.Company 2d397e5c _EOIntegralKeyGlobalID[Company (java.lang.Integer)89]>
> MarksDelegate.editingContext: er.extensions.eof.ERXEC@49198ff2 didMergeChanges:
> May 17 19:28:06 UseTheDelegate[49584] DEBUG NSLog - === Begin Internal Transaction
> May 17 19:28:06 UseTheDelegate[49584] DEBUG NSLog - evaluateExpression: <com.webobjects.jdbcadaptor.MySQLPlugIn$MySQLExpression: "SELECT t0.id, RTRIM(t0.name) FROM Company t0 WHERE t0.id = ?" withBindings: 1:89(id)>
> May 17 19:28:06 UseTheDelegate[49584] DEBUG NSLog - 1 row(s) processed
> May 17 19:28:06 UseTheDelegate[49584] DEBUG NSLog - === Commit Internal Transaction
> C2 saved.
> Application.Application: C2 1274149686265
> Application.Application: C2 1274149686265
> Application.Application: C2 1274149686265
> May 17 19:28:06 UseTheDelegate[49584] DEBUG NSLog - The URL for webserver connect is:
> http://17.246.48.60/cgi-bin/WebObjects/UseTheDelegate.woa/-49584
> The URL for direct connect is:
> http://17.246.48.60:49584/cgi-bin/WebObjects/UseTheDelegate.woa
> May 17 19:28:06 UseTheDelegate[49584] WARN NSLog -
> May 17 19:28:06 UseTheDelegate[49584] WARN er.extensions.appserver.ERXApplication - You are running in development mode with WOAutoOpenInBrowser = false. No browser will open and it will look like the application is hung, but it's not. There's just not a browser opening automatically.
> May 17 19:28:06 UseTheDelegate[49584] DEBUG NSLog - Waiting for requests...
>
> _______________________________________________
> Do not post admin requests to the list. They will be ignored.
> Webobjects-dev mailing list (email@hidden)
> Help/Unsubscribe/Update your Subscription:
>
> This email sent to email@hidden
Attachment:
smime.p7s
Description: S/MIME cryptographic signature
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden