Transaction for getting started with hibernate

Source: Internet
Author: User

Address: Mr. Fan Kai, http://www.iteye.com/topic/264ArticleAlthough it has been around for a long time, it is still awesome

Getting started with hibernate-transaction

Hibernate is a lightweight object encapsulation of JDBC. hibernate itself does not have the transaction processing function. hibernate's transaction is actually the encapsulation of the underlying JDBC transaction, or the encapsulation of JTA transaction, the following is a detailed analysis:

Hibernate can be configured as jdbctransaction or jtatransaction, depending on your configuration in hibernate. properties:

Reference
 
# Hibernate. transaction. factory_class net. SF. hibernate. transaction. jtatransactionfactory # hibernate. transaction. factory_class net. SF. hibernate. transaction. jdbctransactionfactory

 

If you do not configure anything, jdbctransaction is used by default. If you configure it:

Reference
 
Hibernate. transaction. factory_class net. SF. hibernate. transaction. jtatransactionfactory

Jtatransaction will be used

Whether you want hibernate to use jdbctransaction or jtatransaction, my advice is to keep it in the default state, as shown below:

Reference
 
# Hibernate. transaction. factory_class net. SF. hibernate. transaction. jtatransactionfactory # hibernate. transaction. factory_class net. SF. hibernate. transaction. jdbctransactionfactory

In the following analysis, I will give the reason.

I. JDBC transaction

Let's take a look at ourCodeExample:

Java code

 
Session session =SF. opensession (); transaction TX=Session. begintransactioin ();... session. Flush (); Tx. Commit (); Session. Close ();;

This is the default situation. When you use hibernate transaction in code, it is actually jdbctransaction. So what exactly is jdbctransaction? Let's see.Source codeIt is clear:

Class in source code of hibernate2.0.3

Java code:

 Net. SF. hibernate. transaction. jdbctransaction:  Public   Void Begin (); Throws  Hibernateexception {log. debug ( "Begin" );;  Try  {Toggleautocommit = Session. Connection ();. getautocommit ();; If (Toggleautocommit); Session. Connection ();. setautocommit ( False  );;}  Catch  (Sqlexception E); {log. Error ( "Begin failed" , E );;  Throw   New Transactionexception ("begin failed with SQL exception :" , E);} begun = True  ;} 

This is the method for starting transaction. Do you see connection (). setautocommit (false? Are you familiar with this?

Let's take a look.

Java code
 Public   Void Commit (); Throws  Hibernateexception {  If (! Begun ); Throw   New Transactionexception ("transaction not successfully started" ); Log. debug ( "Commit" );;  Try  {  If (Session. getflushmode ();! =Flushmode. Never); Session. Flush ();;  Try  {Session. Connection ();. Commit (); committed = True  ;}  Catch  (Sqlexception E); {log. Error ( "Commit failed" , E );;  Throw   New Transactionexception ("Commit failed with SQL exception :" , E );;}}  Finally {Session. aftertransactioncompletion () ;}toggleautocommit ();;} 

This is the submission method. Have you seen connection (). Commit? I don't need to talk about the following. This class of code is very simple and easy to understand. Through reading, we can understand what hibernate's transaction is doing? Now I have translated the example written in hibernate into JDBC, and you can see it at a Glance:

Java code
 
Connection conn =...; <--- session =SF. opensession (); Conn. setautocommit (False); <--- Tx =Session. begintransactioin ();;...<---... Conn. Commit ();;<---TX. Commit (); (two sentences on the left); Conn. setautocommit (True); Conn. Close ();;<--- Session. Close ();;

See it. hibernate's jdbctransaction is essentially Conn. there is no mystery at all, but in hibernate, when the session is opened, it will automatically Conn. setautocommit (false). Unlike JDBC, the default value is true. Therefore, it does not matter if you do not write a commit statement. Because hibernate has disabled autocommit, when you use hibernateProgramIf no transaction is written, the database does not respond at all.

Ii. jtatransaction

If you use hibernate in EJB, or you want to use JTA to manage long transactions across sessions, you need to use jtatransaction. Let's look at an example:

Java code

 
Javax. transaction. usertransaction Tx =NewInitialcontext ();. Lookup ("javax. transaction. usertransaction"); Session S1=SF. opensession ();... s1.flush (); s1.close ();... session S2=SF. opensession ();... s2.flush (); s2.close (); Tx. Commit ();;

This is a standard piece of code using JTA. transaction is cross-session, and its lifecycle is longer than session. If you use hibernate in EJB, It is the simplest. You should not write any transaction code, you can directly configure the transaction usage of the XX method on the EJB deployment descriptor. 

Now let's analyze the source code of jtatransaction, net. SF. hibernate. transaction. jtatransaction:

Java code
 
Public VoidBegin (initialcontext context,... ut=(Usertransaction); context. Lookup (utname );;...

Are you clear? Is the same as the Code Tx = new initialcontext (). Lookup ("javax. transaction. usertransaction") I wrote above?

Java code
Public VoidCommit ();......If(Newtransaction); ut. Commit ();;...

The control of jtatransaction is a little complicated, but it can still be clearly seen how hibernate encapsulates JTA's transaction code.

But have you seen any problems? Think about it,Hibernate transaction is obtained from the session, Tx = session. begintransaction (), submit TX first, and then session. close, which fully complies with the Operation Sequence of the JDBC transaction, but this sequence is totally different from the transactioin Operation Sequence of JTA !!! JTA starts transaction first, then starts the session, closes the session, and finally submits the transaction. Therefore, when you use the transaction of JTA, never use the transaction of hibernate, it should be used like the JTA code snippet above.

Summary:

1. Use hibernate on JDBC

You must write the hibernate transaction code. Otherwise, the database does not respond. In this case, the transaction of Hibernate is connection. Commit.

2. Use hibernate on JTA

Write the transaction code of JTA. Do not write the transaction code of hibernate. Otherwise, the program reports an error.

3. Use hibernate on EJB

Do not write any transactioin code. configure it in the EJB deployment descriptor.

Java code:

 
| ---CMT (container managed transaction );| ---BMT (bean managed transaction );| ----JDBC transaction| ---- JTA transaction

Q &:

Robbin:
You said, "hibernate's jdbctransaction is essentially Conn. there is no mystery at all, but in hibernate, when the session is opened, it will automatically Conn. setautocommit (false). Unlike JDBC, the default value is true. Therefore, it does not matter if you do not write a commit statement. Because hibernate has disabled autocommit, when you use hibernate, if you do not write transaction in the program, the database will not respond"
However, when SF. opengsession () is used, there is no setautocommit (false). What I want to ask is, if no transaction code is written, such as Java code:

 
Session S =SF. opensession (); ...... S. Close ();;

Will the database respond? (the default autocommit is true ).

In addition, I would like to ask:
1. S. Flush () is required?
2. S. Close () Is it necessary to close
As you mentioned above:

Java code
Javax. transaction. usertransaction Tx =NewInitialcontext ();. Lookup ("javax. transaction. usertransaction"); Session S1=SF. opensession ();... s1.flush (); s1.close ();... session S2=SF. opensession ();... s2.flush (); s2.close (); Tx. Commit ();;

S1 is not closed. Is it possible to use S1 in code that uses S2 for operations (I think this is more resource-saving and does not require repeated connections or shutdown)

Reference
 
But when SF. opengsession (), there is no setautocommit (False), I want to ask, if you do not write any transaction code, such as session s=SF. opensession (); ...... S. Close (); will the database respond? (in this case, autocommit should be set to true by default ).

No response. When SF. opensession () is used to create a session instance, conn. setautocommit (false) has been called.

Reference

In addition, I would like to ask:1. S. Flush () is required?2. S. Close () Is it necessary to close

S. Flush is not required. S. Close () will call S. Flush () once ()

S. Close () should be closed normally unless you use threadlocal to manage the session.

Reference

 
S1 is not closed. Is it possible to use S1 in code that uses S2 for operations (I think this is more resource-saving and does not require repeated connections or shutdown)

The role of JTA cannot be seen in this example.
Hypothesis

Java code
 
Class A {find (); {session S1=SF. opensession ();... s1.flush (); s1.close ();;}}
 
Class B {find (); {session S2=SF. opensession ();... s2.flush (); s2.close ();;}}
Main {TX=...; A. Find (); B. Find (); Tx. Commit ();;}

Do you understand? The transaction management of JTA is called across classes.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.