Question/Issue with ORM transaction implementation

Yes, a property for it.

The property becomes a variable scope variable so you can use the DSL to inject it or use the setter approach or the constructor approach. Anyway you see fit.

Luis F. Majano
President
Ortus Solutions, Corp

ColdBox Platform: http://www.coldbox.org
Linked In: http://www.linkedin.com/pub/3/731/483
Blog: http://www.luismajano.com
IECFUG Manager: http://www.iecfug.com

But this is for the current ORMService.save() I am talking about, and in what you are talking about with the init(useTransaction=false) then I wouldn’t see a problem then, because it would default to false which is good.

Regards,

Andrew Scott

http://www.andyscott.id.au/

Yes, you got it Andrew!

You can turn auto transactions on/off in the following methods:

delete
deleteAll
deleteByID
deleteWhere
saveAll
save

Or you can pass an OPTIONAL argument: transactional, which can do a-la-carte on/off

I also updated the services so they know when the transaction aspect has placed a transaction already so it just joins it instead of a new one. So it doesn’t matter which one starts it.

Luis F. Majano
President
Ortus Solutions, Corp

ColdBox Platform: http://www.coldbox.org
Linked In: http://www.linkedin.com/pub/3/731/483
Blog: http://www.luismajano.com
IECFUG Manager: http://www.iecfug.com

Curious: Do people really have database interactions without transactions even now, in 2011?

Reading that someone thinks it is common, let alone “more common” to not use transactions is shocking to me. Why wouldn’t you use transactions??

Can you post an example of how to do this using the variables scope?
Say I had this in my handler:

property name="service" inject="entityService";

How would I change a property on that injected entity?

service.setUseTransactions(false);

Luis F. Majano
President
Ortus Solutions, Corp

ColdBox Platform: http://www.coldbox.org
Linked In: http://www.linkedin.com/pub/3/731/483
Blog: http://www.luismajano.com
IECFUG Manager: http://www.iecfug.com

I thought by default that it is injected into the variable space, maybe it
is instance then.

Which means you now need scope="variable" on your property.

Regards,
Andrew Scott
http://www.andyscott.id.au/

That is not what I was talking about Matt, transactions and ORM session management are two different things.

Regards,

Andrew Scott

http://www.andyscott.id.au/

ok, this is on the development branch, can you please try it out.

Thanks!

Luis F. Majano
President
Ortus Solutions, Corp

ColdBox Platform: http://www.coldbox.org
Linked In: http://www.linkedin.com/pub/3/731/483
Blog: http://www.luismajano.com
IECFUG Manager: http://www.iecfug.com

Sure downloading now.

Regards,

Andrew Scott

http://www.andyscott.id.au/

Btw anyone else having issues with Chrome and github?

http://github.com/coldbox

throws this error in Chrome.

This webpage is not available

The webpage at ColdBox Platform · GitHub might be temporarily down or it may have moved permanently to a new web address.

Error 205 (net::ERR_CERT_UNABLE_TO_CHECK_REVOCATION): Unknown error.

Works fine in FireFox though.

Regards,

Andrew Scott

http://www.andyscott.id.au/

I (we) think you should use always transactions.

Our argument is that the CB orm service is defaulting to committing
small transactions (i.e. a single entity save) rather than letting us
define our own transaction boundaries by default. If I have a service
method that saves multiple entities, I don't want CB committing every
time I call save()

.brett

I also updated the services so they know when the transaction aspect has
placed a transaction already so it just joins it instead of a new one. So it
doesn't matter which one starts it.

NICE!!!! I think this will be a big improvement Luis.

thanks,

.brett

working here....

Aahh. Gotcha. My bad for misunderstanding the previous statements. :slight_smile:

lol! that's not what I was asking :slight_smile: That is almost as bad as using
the argument.

BaseORMService function init(string queryCacheRegion=“ORMService.defaultCache”,

boolean useQueryCaching=false,

boolean eventHandling=true,

boolean useTransactions=true){

should be

BaseORMService function init(string queryCacheRegion=“ORMService.defaultCache”,

boolean useQueryCaching=false,

boolean eventHandling=true,

boolean useTransactions=false){

I can give you an example where useTransactions=true, when ColdFusion is managing the session will fail. This is why I said that the use of transactions should be false if one is getting ColdFusion to manage the sessions, as this is the common way 99% of developers are going to program their apps, then this will continue to fail and cause issues.

And is why I am constantly changing this code to false so ColdBox works in my current applications. True that I would only have to do this once now, but the problem here is that I have something like this in my code at the moment.

Read in a cfquery from another database source called query 1

Loop over query1

Create a transient Object1

Populate transient object1

Read in a cfquery from another database source called query 2

Loop over query2

Create a new transient object2

Populate transient object

Save transient object2 or make it persistent

Loop end

Save transient object1

Loop end

Now here is the problem that I have with transient default to true, when ColdFusion is managing sessions. If the loop over query2 fails when saving the transient object, it will do a transaction, then commit or rollback depending on what is required. This when ColdFusion managers sessions throws a hibernate exception, basically saying that the session is closed when it eventually gets to the outer save of object1.

Another example of where this will fail, is if you have an ORM Event that does gets the current ORMSession. Then does a HQL update/delete to the DB, this will also throw a session is closed when trying to save the transient object1.

In all my examples I have had to default the use of transaction to false.

Sorry Luis I am still not convinced that I see a use case of defaulting the use of transactions in the ORMService to true, the more I use it in real world I am finding the opposite should be true, and the use of transactions set to false by default. Especially with something I am about to release, it not only has ORMEvents that handle preInsert, and postDelete but it also requires that the use of transaction = false. Which means anyone who needs to use these Events, on this entity will be forced to change their code to use transaction=false.

Regards,

Andrew Scott

http://www.andyscott.id.au/

Bizare, maybe I have a corrupt certificate stored for that site then. I
noticed it about a week or so ago, but as I very infrequently visit it. It
was no big deal to fire up fireFox.

Might have to google the error to see what turns up.

Regards,
Andrew Scott
http://www.andyscott.id.au/

yeah I can see that breaking quite easily using the cb orm service
with transactions enabled. Are you saving object1 and object2 to
separate datasources as well?

I haven't tested but I have a suspicion that the transaction aspect
will have problems with multiple datasources in a single aspect.

I haven't seen anything in cb that makes my lightbulb go off why it is
using a hibernate session transaction rather than using cf's
transaction handling, as I understand it all of this would of been a
non issue if it was using cftransaction.

from http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7c6b.html

"You can now nest cftransaction tags. Typically, ColdFusion 9 does not
support nested transactions, but you can embed one cftransaction tag
inside another. If you nest these tags, only the outermost
cftransaction tag takes effect.
This feature lets you write functions that must run in a transaction
without considering whether the function is called by code that is
inside a cftransaction tag. Use a cftransaction tag in the function.
If the calling code is in a transaction, the tag has no effect. If the
calling code is not in a transaction, the tag starts the transaction."

CB appears to be managing the nesting with a single global request
variable, but there are other cool things with cftransaction that I'd
like to hug. Namely savepoints, nested (can it be nested), and
isolation.

Seemingly we lose all that with the transaction aspect and the orm
service. I'm still going deeper (Inception!) but I know there will be
other problems. I would only recommend the orm service and
transaction aspect as it is now with reservations. But this is the
first iteration of it and I want to make it work, so I am going to
continue to use it and provide the feedback.

.brett

No the transient objects that end up getting persisted are from the same
datasource, the queries are coming from another datasource.

The pseudo code that I posted was a conversion utility to take data from an
older database, and convert it to the new application data structure. And as
this is an ORM project I then used the ORM to create and save the data.

Transactions will NOT work across multiple datasources, so your suspicion
was correct. And even if I start to manage the session myself, in the
example I provided, the transaction set to true also throws a closed session
error.

There is about 5 posts on this in the last year, and is why I keep modifying
the use of transactions in save() from the ORMService. Because every real
world example ends up not working with it, I asked for it to default to
false for this reason over 8 months ago.

And I just posted another example on a new blog entry I just wrote up, and
even with that, the save() in ORMService has to be set to default of false,
or it will not work with any of you application's code.

These are two examples that I know don't work, with the defaults set to
true.

Regards,
Andrew Scott
http://www.andyscott.id.au/

From: coldbox@googlegroups.com [mailto:coldbox@googlegroups.com] On
Behalf Of Brett
Sent: Saturday, 9 April 2011 11:57 AM
To: ColdBox Platform
Subject: [coldbox:9361] Re: Question/Issue with ORM transaction
implementation

yeah I can see that breaking quite easily using the cb orm service with
transactions enabled. Are you saving object1 and object2 to separate
datasources as well?

I haven't tested but I have a suspicion that the transaction aspect will

have

problems with multiple datasources in a single aspect.

I haven't seen anything in cb that makes my lightbulb go off why it is

using a

hibernate session transaction rather than using cf's transaction handling,

as I

understand it all of this would of been a non issue if it was using
cftransaction.

from
http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859
461172e0811cbec22c24-7c6b.html

"You can now nest cftransaction tags. Typically, ColdFusion 9 does not
support nested transactions, but you can embed one cftransaction tag

inside

another. If you nest these tags, only the outermost cftransaction tag

takes

effect.
This feature lets you write functions that must run in a transaction

without

considering whether the function is called by code that is inside a
cftransaction tag. Use a cftransaction tag in the function.
If the calling code is in a transaction, the tag has no effect. If the

calling code

is not in a transaction, the tag starts the transaction."

CB appears to be managing the nesting with a single global request

variable,

but there are other cool things with cftransaction that I'd like to hug.

Namely

savepoints, nested (can it be nested), and isolation.

Seemingly we lose all that with the transaction aspect and the orm

service.

I'm still going deeper (Inception!) but I know there will be other

problems. I

would only recommend the orm service and transaction aspect as it is now
with reservations. But this is the first iteration of it and I want to

make it