questions about UnitOfWork.REQUEST and transactions

17 views
Skip to first unread message

Michael Day

unread,
Aug 17, 2010, 10:43:59 PM8/17/10
to warp-core
Hi,

I'm hoping someone could shed some light on how warp-persist is
supposed to work. I'm using PersistenceFilter with UnitOfWork.REQUEST
and hibernate. My changes are being persisted to the database even
when I have not specified @Transactional anywhere. Is this supposed
to happen?

My unit tests have the opposite problem. I use WorkManager to wrap my
tests in a UnitOfWork, and I specify @Transactional on both the test
method and the service method that I'm calling from the test.
Regardless, no transaction is started, and changes do not get
persisted.

I understand that Spring's OSIV keeps the FlushMode set to NEVER when
outside a transaction and temporarily sets it to AUTO during a
transaction. Is warp supposed to do this?

Thanks,

Michael Day

Dhanji R. Prasanna

unread,
Aug 20, 2010, 9:52:43 AM8/20/10
to warp...@googlegroups.com
On Wed, Aug 18, 2010 at 12:43 PM, Michael Day <blak...@gmail.com> wrote:
Hi,

I'm hoping someone could shed some light on how warp-persist is
supposed to work. I'm using PersistenceFilter with UnitOfWork.REQUEST
and hibernate.  My changes are being persisted to the database even
when I have not specified @Transactional anywhere.  Is this supposed
to happen?

This will happen depending on your database. If the commit mode of the sql connection is AUTO (MySQL) then yes an implicit transaction will be started. Usually databases don't allow you to do anything (including reading) unless you're inside a transaction so they will complain vociferously otherwise.

There is a lot of literature about why it doesn't make sense to read unless you're inside a txn. I'll leave it to say it's not so much a WP thing as it is a combination of database, hibernate and session settings.
 

My unit tests have the opposite problem.  I use WorkManager to wrap my
tests in a UnitOfWork, and I specify @Transactional on both the test
method and the service method that I'm calling from the test.
Regardless, no transaction is started, and changes do not get
persisted.

I understand that Spring's OSIV keeps the FlushMode set to NEVER when
outside a transaction and temporarily sets it to AUTO during a
transaction.  Is warp supposed to do this?

You can do this--but it's a hack to create read-only transactions. In warp-persist (hibernate only) you can specify @Transactional(type=READ_ONLY) or something similar which does roughly the same trick.

Dhanji.

Dan Retzlaff

unread,
Aug 20, 2010, 10:13:12 AM8/20/10
to warp...@googlegroups.com
Hi Michael,

I could have written the same questions two days ago, and even started
drafting the message to warp-core. Pardon some irrelevant details in
this message; my goal is partially to document the knowledge that
would have helped me. :)

First, it's important to differentiate session open/close from
transaction begin/end. The PersistenceFilter and WorkManager open and
close *sessions*. They should be used with Hibernate's
ManagedSessionContext (i.e.
hibernate.current_session_context_class=managed). The common
alternative, ThreadLocalSessionContext
(hibernate.current_session_context_class=thread) will automatically
create a session when SessionFactory.getCurrentSession() is called,
requires that a transaction is started, and automatically closes the
session when that transaction is ended. That is clearly not the
session lifecycle expected with UnitOfWork.REQUEST and
PersistenceFilter or WorkManager. If you want
ThreadLocalSessionContext, you should be using UnitOfWork.TRANSACTION
without PersistenceFilter or WorkManager.

As for *transaction* management, that's where the PersistenceService
and those @Transactional annotations come in. Note that Hibernate
itself does not require you to put session.beginTransaction() and
session.endTransaction() around your operations. If you omit these,
then Dhanji's comment applies: with MySQL, an implicit transaction
gets used for each operation, and the operations get sent on flush.

I can't explain the difference in behavior between your unit tests and
servlet, except to suggest that some Hibernate or database
configuration is different (flush mode?). After all, the
PersistenceFilter just uses WorkManager behind the scenes. Also, check
that you're instantiating the @Transaction annotated classes through
Guice so the PersistenceService's interceptor can take effect.

Hope that helps.

Dan

> --
> You received this message because you are subscribed to the Google Groups "warp-core" group.
> To post to this group, send email to warp...@googlegroups.com.
> To unsubscribe from this group, send email to warp-core+...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/warp-core?hl=en.
>

Reply all
Reply to author
Forward
0 new messages