well you are decorating the session not the session source of cause... .

2013/10/25 Martin Kersten <martin.kersten...@gmail.com>

> >> Perhaps you want a @MaybeCommitAfter ;)
>
> What about simply having @WriteTransaction (und @ReadTransaction, since
> lacking support for read transactions is the biggest performance issue when
> dealing with databases). If you are inside a method annotated with
> @WriteTransaction it is ignored. If nesting write within a read transaction
> fails (there is something wrong with your service methods / thinking). And
> also wrapping the session source (decorate) and checking on any
> save+/update/delete  + query if a transaction was set makes it crystal
> clear if you messed up the transactional thingy. Also using @CommitAfter
> inside a @XxxxTransaction fails, since you can not commit inside it without
> breaking the meaning.
>
> This would make it possible to have a good implementation which is self
> explaining, would only cost two hours to build and test (at least I havent
> spent an hour in total I think). And it wont break the backward
> compatibility with @CommitAfter.
>
>
> 2013/10/25 Martin Kersten <martin.kersten...@gmail.com>
>
>> And George, read this one:
>> http://stackoverflow.com/questions/10143880/hibernate-queries-much-slower-with-flushmode-auto-until-clear-is-called.
>> It explains why you experience the slow downs and what is it causing it.
>>
>>
>> 2013/10/25 Martin Kersten <martin.kersten...@gmail.com>
>>
>>> You might also want to use such kind of a utility that allows you to run
>>> in transaction:
>>>
>>> public interface InTransaction<T> {
>>>       public T run(Session session);
>>> }
>>>
>>> public static <T> T DatabaseUtil.process(InTransaction<T>
>>> transactionalRunnable) {
>>>       try {
>>>            Session session = currentSession(); //or newSession()
>>>            if(!session.getTransaction().isActive())
>>>                  session.beginTransaction();
>>>            T result = transactionalRunnable.run(session);
>>>            if(!session.getTransaction.isActive()) {
>>>                session.getTransaction().commit();
>>>                session.clear();
>>>            }
>>>       }
>>>       catch(RuntimeException e) {
>>>            if(session.getTransaction().isActive()) {
>>>                 session.getTransaction().rollback();
>>>                 session.clear(),
>>>            }
>>>       }
>>>       finally {
>>>            //session.close(); //if you created a new one
>>>       }
>>>  }
>>>
>>>
>>> This way you can control the whole transactional process while only
>>> doing:
>>>
>>> List<Product> product = DatabaseUtil.process(new
>>> InTransaction<List<Product>>() {
>>>       List<Product> run(Session session) {
>>>            //getUser etc are all static methods fetching from a
>>> ThreadLocal RequestContext object so you dont need
>>>            //to inject / pass along parts of your model in every
>>> component/page
>>>            UserInfo user = getUser();
>>>            userStats.countUserRequest(user); //changes the database;
>>>            return queryProductsForUser(user, session); //returning a list
>>>       }
>>> }
>>>
>>> This example is just made up to demonstrate that you can return a
>>> List<Product> or Integer or if you have nothing to return
>>> a Void instance.
>>>
>>> The DatabaseUtil class I use for everything that happends outside of a
>>> request therefore when I have to control the sessions
>>> being opened, closed and manage the transaction. This way you even not
>>> run into any difficult with nesting (you can not
>>> leave the transaction (since it is an enclosed try catch block),
>>>
>>> I have set my session to automatically clear the persistence context on
>>> commit.
>>> You can do this by ((SessionImpl)session).setAutoClear(true).
>>>
>>> And of cause checking if a transaction is active can be extracted to a
>>> private method to value the DRY principle.
>>>
>>>
>>>
>>>
>>> 2013/10/25 Martin Kersten <martin.kersten...@gmail.com>
>>>
>>>> >              session.flush();
>>>> >              session.clear();
>>>> >              hibernateSessionManager.commit();
>>>>
>>>> This is wrong.
>>>> First on commit you will do the flush automatically (flush means all
>>>> changes are written to the database (performing outstanding updates,
>>>> inserts, deletes))
>>>> Clear clears the persistence context of all entities not taking part on
>>>> any outstanding flush event (as far as I remember) therefore Hibernate does
>>>> a deep
>>>> inspection of the active entities and removes all entities that were
>>>> not encountered during that process.
>>>> Commit commits the entities.
>>>>
>>>> So the correct usage is:
>>>> session.getTransaction().commit();
>>>> session.clear();
>>>> session.beginTransaction();
>>>>
>>>> (without the clear its what HibernateSessionManager is doing with the
>>>> session bound to the current thread).
>>>>
>>>>
>>>>
>>>>
>>>> 2013/10/25 Martin Kersten <martin.kersten...@gmail.com>
>>>>
>>>>> Use:
>>>>>
>>>>> @Inject
>>>>> Session session; //current session bound to the current thread
>>>>>
>>>>>
>>>>> or
>>>>>
>>>>> @Inject
>>>>> HibernateSessionSource source; + source.create() for a really new
>>>>> session (CommitAfter would not work with newly created one);
>>>>>
>>>>> Using the Manager does give you only the session associated with the
>>>>> current thread as would @Inject Session session; would do.
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> 2013/10/25 George Christman <gchrist...@cardaddy.com>
>>>>>
>>>>>> So I guess I'm still a little confused as to what is the best to do
>>>>>> it.
>>>>>> @CommitAfter seems to work fine for individual transactions but does
>>>>>> not
>>>>>> work well with batch jobs do to it holding on to the object in memory.
>>>>>> Anyhow, I could not figure out how to get Martins
>>>>>> session.getTransaction()
>>>>>> to work, however I did end up getting the following code to work.
>>>>>> Could
>>>>>> someone tell me if I'm doing this correctly? Also should I be closing
>>>>>> and
>>>>>> rolling back the transaction?
>>>>>>
>>>>>>      //Mock scenario
>>>>>>
>>>>>>     @Inject
>>>>>>     private HibernateSessionManager hibernateSessionManager;
>>>>>>
>>>>>>     public void onActionFromTest() {
>>>>>>         Session session = hibernateSessionManager.getSession();
>>>>>>
>>>>>>         for (int i = 0; i < 100000; i++) {
>>>>>>             employee = new Employee("George " + i);
>>>>>>
>>>>>>             session.save(employee);
>>>>>>
>>>>>>             if (i % 250 == 0) {
>>>>>>                 session.flush();
>>>>>>                 session.clear();
>>>>>>                 hibernateSessionManager.commit();
>>>>>>             }
>>>>>>         }
>>>>>>
>>>>>>         session.flush();
>>>>>>         session.clear();
>>>>>>         hibernateSessionManager.commit();
>>>>>>
>>>>>>
>>>>>>
>>>>>> On Fri, Oct 25, 2013 at 9:07 AM, Thiago H. de Paula Figueiredo <
>>>>>> thiag...@gmail.com> wrote:
>>>>>>
>>>>>> > On Fri, Oct 25, 2013 at 10:53 AM, Barry Books <trs...@gmail.com>
>>>>>> wrote:
>>>>>> >
>>>>>> > While it's true you can run into problems by nesting @CommitAfter
>>>>>> the same
>>>>>> > > can be said about nesting any commits. The Tapestry database
>>>>>> model is
>>>>>> > > simple. There is one connection per request and when you call
>>>>>> commit it
>>>>>> > > does a commit.
>>>>>> > >
>>>>>> >
>>>>>> > <pedantic>
>>>>>> > Tapestry itself doesn't have any database model. It's a web
>>>>>> framework and
>>>>>> > nothing else. You can use it with any database, including none.
>>>>>> > Tapestry-Hibernate is a package that provides *simple* support for
>>>>>> > Hibernate and should be used in *simple* scenarios. If you need
>>>>>> something
>>>>>> > that's not simple, like any transaction handling not supported by
>>>>>> > @CommitAfter, use Tapestry and some transaction handler (EJB,
>>>>>> Spring-TX,
>>>>>> > etc) but not Tapestry-Hibernate.
>>>>>> > </pedantic>
>>>>>> >
>>>>>> >
>>>>>> >
>>>>>> > >
>>>>>> > >
>>>>>> > > On Fri, Oct 25, 2013 at 7:31 AM, Lance Java <
>>>>>> lance.j...@googlemail.com
>>>>>> > > >wrote:
>>>>>> > >
>>>>>> > > > I'm assuming a fork is broken too because it's no good for
>>>>>> eating soup?
>>>>>> > > > Sounds like you need a spoon, it's easy to write your own
>>>>>> annotation...
>>>>>> > > > Perhaps you want a @MaybeCommitAfter ;)
>>>>>> > > >
>>>>>> > >
>>>>>> >
>>>>>> >
>>>>>> >
>>>>>> > --
>>>>>> > Thiago
>>>>>> >
>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> George Christman
>>>>>> www.CarDaddy.com
>>>>>> P.O. Box 735
>>>>>> Johnstown, New York
>>>>>>
>>>>>
>>>>>
>>>>
>>>
>>
>

Reply via email to