find out if there is a transaction associated with current thread? - jta

There is a method commit in user transaction class. When we do commit on it, first it finds that if there is a transaction associated with this thread. My question is how at core java level we can find out if there is a transaction associated with current thread?
(i know its a internal process to JTA apis but still interested )

One simple way I can think of is to keep a map with Thread reference as 'key' and the Transaction object as 'value'. For a thread with no transaction created in the past, there will be no such key in the map and hence UserTransaction implementation can decide to throw an exception.
Any line of code can know which Thread it is by Thread.currentThread().
Hope that helps.
Thanks,
Nitin

Related

Cannot delete from sql using #Transactional with Spring and Hibernate

I have #Transactional set up correctly, however with the following method "success" is returned but the record is not deleted from the table:
#Transactional
public void deleteLimXrefHvo(LimitXrefHvo limitXrefHvo){
getSession().delete(getTableId(limitXrefHvo));
}
I tried with the method getTableId annotated with #Transactional as well and that does not solve the problem. I've also called getTableId and stored the return value in a variable before passing it into delete() and that did not work, either.
The only thing that works that I've tried is to add getSession().flush(); after the delete transaction. If I have #Transactional set up, then I shouldn't need to flush after. What am I missing?
The session may live longer than a single transaction. This seems to be the case here. From the JSR-220 5.6:
A container-managed persistence context may be defined to have either
a lifetime that is scoped to a single transaction or an extended
lifetime that spans multiple transactions, depending on the
PersistenceContextType that is specified when its EntityManager is
created. This specification refers to such persistence contexts as
transaction-scoped persistence contexts and extended persistence
contexts respectively.
I know you said 'Spring' and not Java EE container but I believe it boils down to the same behavior.
This is to say that session-scope is not equal transaction-scope. For your specific problem you may check:
Is ´deleteLimXrefHvo()´ called from another #Transactional method (hint: what about transaction propagation)?
What flush mode does the transaction have (manual?)?
Investigate your logs, in particular I would set the logging level to DEBUG on your transaction manager to see exactly what it's doing.
it was getTableId that was causing the problem. getTableId calls its own getSession(), and because of that, I have to flush(). there is no getting around it. makes sense, though.

Nhibernate: Is it possible to throw an exception if Save() is called without beginning a transaction

I was wondering if we can some how extend NHiberate to throw an exception if a piece of code attempted to save an object to a database without beginning a transaction? Since beginning a transaction is a requirement for calling Save() to work properly, I can't see a programmer calling Save() without beginning a transaction in the first place.
Solution is not in the exception throwing. It is about keeping us (developers on the project) aware of what and where we are doing
1) Project shared approach. Firstly, explain to the team how the Architecture of application works. All team members should now, that Unit of Work, or Session per Request patterns are in place.
2) The FlushMode. Secondly, explain the concept of the Session object. ISession. Save() or Update() is far away from SQL execute INSERT or UPDATE. What count is the ISession.Flush(). And (based on the first step) we can decide when that Flush() happens.
I would suggest setting the FlushMode to on Commit or None (with explict call). And then, if a team member would like to Execute any write command - one standard place, one common way (used on the project) will guide hin/her.
The call Session.Flush() should/will/must be wrapped in a transaction.

NSManagedObject changed properties after save

Is it possible to find out which properties were saved on a managed object after the save occurs? For example, I have someone listening for managed object context saves, (NSManagedObjectContextDidSaveNotification) and I want to know which properties on the objects were saved.
The NSManagedObjectContextDidSaveNotification does contain all three bits of information you would need to sync with a server. Check the [notification userInfo] and you will find three sets inside: NSInsertedObjectsKey, NSUpdatedObjectsKey, and NSDeletedObjectsKey
If you want to know what properties on an entity have changed that would require that you track them yourself using KVO. I would recommend against this as the odds of that level of effort being worth it over just pushing the entire object up to a server are slim.
Update #2
On further poking around:
From the NSManagedObjectContextWillSaveNotification you could loop through each set and reference the changedValues method. You could keep a reference to that dictionary until after you receive the NSManagedObjectContextDidSaveNotification and then process the changes. Still sounds very heavy to me.
Update
What is your end goal?!?!
If you are trying to figure out what to push to a server then being at the attribute level is too low. You should be syncing at the entity level.
If you are just trying to keep some internal consistency inside of your application then you are thinking way, way too low level. This is a solved problem. Core Data solved it.
Why don't you get them when they are about to be saved. Subscribe to NSManagedObjectContextWillSaveNotification and check insertedObjects, updatedObjects and deletedObjects of the NSManagedObjectContext.
Update:
Even easier, get the user info of the NSManagedObjectContextDidSaveNotification
From the documentation:
Typically, on thread A you register for the managed object context
save notification, NSManagedObjectContextDidSaveNotification. When you
receive the notification, its user info dictionary contains arrays
with the managed objects that were inserted, deleted, and updated on
thread B.
http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/coredata/Articles/cdConcurrency.html#//apple_ref/doc/uid/TP40003385-SW1
Here's the solution I settled with. I have one singleton class that is notified when a context saves. The NSManagedObjectContextWillSave notification tells me which things have changed so I store them in a dictionary with the key being the context that saved. Then when I get the NSManagedObjectContextDidSave notification, I check the dictionary for the associated context. Finally, I remove that entry from the dictionary. Does that seem reasonable?

Monorail, nhibernate and session-per-request pattern

I need some insights and thoughts about a refactoring I'm about to do to our web-app.
We initially used the session-per-request pattern with NHibernate and ActiveRecord by using the On_BeginRequest / On_EndRequest in the HttpApplication to create and dispose the session. Later on, we realized that any DB-related exceptions got thrown outside of our monorail-context, meaning that our rescues didn't kick in. As another sideeffect, we didn't have the option to fully skip creation of NHibernate sessions in any action, which in some cases would be desirable.
So we rewrote it to create sessions in Initialize() / Contextualize() in our base controller, and disposed them in the Dispose() of our base controller. We also Rollback the session in our rescue controller to prevent any half written changes to the DB. So far, so good. The reason for doing it in the Dispose() is because we want it to live through the view-rendering, because of lazy-loading reasons aswell as viewcomponents that needs to get a session (we could switch to units-of-work for the viewcomponents, but they don't seem to have a Dispose()...)
However, I'm experiencing some deadlock issues where we have started transacations in the DB that isn't getting rollbacked nor committed and I can't get my head around it, mostly because of the mess we've made with this approach...
So I found this article: http://hackingon.net/post/NHibernate-Session-Per-Request-with-ASPNET-MVC.aspx
And I thought, "Filters, we can use that in MonoRail too!", because it can kick in on BeforeAction and AfterRendering.
My questions then are:
What happens if an Exception occurs in the filter?
Will AfterRendering fire even if an Exception occurs in the action or the rendering?
Would you recommend this approach, if not, what are your suggestion instead?
Any pointers are very much appreciated!
You need an application error handler to care of exception handling.
Attach a debugger and find out.
Probably not (even though it is my article). It doesn't work with RenderAction. Best to use an IoC container to control the lifetime of connections.

How to ensure that NHibernate is inside a transaction when saving, updating or deleting?

I'd like to ensure, that when I'm persisting any data to the database, using Fluent NHibernate, the operations are executed inside a transaction. Is there any way of checking that a transaction is active via an interceptor? Or any other eventing mechanism?
More specifically, I'm using the System.Transaction.TransactionScope for transaction management, and just want to stop myself from not using it.
If you had one place in your code that built your session, you could start the transaction there and fix the problem at a stroke.
I haven't tried this, but I think you could create a listener implementing IFlushEventListener. Something like:
public void OnFlush(FlushEvent #event)
{
if (!#event.Session.Transaction.IsActive)
{
throw new Exception("Flushing session without an active transaction!");
}
}
It's not clear to me (and Google didn't help) exactly when OnFlush is called. There also may be an implicit transaction that could set IsActive to true.
If you had been using Spring.Net for your transaction handling, you could use an anonymous inner object to ensure that your DAOs/ServiceLayer Objects are always exposed with a TransactionAdvice around their service methods.
See the spring documentation for an example.
To what end? NHProf will give you warnings if you're not executing inside a transaction. Generally you should be developing with this tool open anyway...