Principle [Source resolution]spring in @transactional,propagation.supports, as well as Hibernate Session, and JDBC Connection Association

Source: Internet
Author: User

Spring bundle Hibernate.

Clip:

One

1. What does Spring do with Propagation=propagation.supports?

2. When does Spring generate hibernatesession?

3. What are the effects, similarities and differences between Propagation=propagation.supports and Propagation=propagation.require on the generation session?

3.1. What are the implications, commonalities, and differences between the @transaction and configuration @transaction (Propagation=propagation.supports) that are not configured to generate the session?

4. When does Spring get the jdbcconnection setting from the thread pool Setautocommit (false)?

Second, two kinds of non-session conditions to obtain the session, a mistake, a normal

Thirdly, when can we get a non-transactional Session?

Problem:

One.

1. What does Spring do with Propagation=propagation.supports?

2. When does Spring generate hibernatesession?

3. What are the effects of propagation=propagation.supports and Propagation=propagation.require on generating a session?

Common points: will enter Aspect section processing, try to create a new session, open transaction, can be obtained. Transactionstatus

difference: The former successfully opens the transaction, the latter is not turned on, but a configuration that agrees to lazy loading session is set. See the code below for details.

3.1. Is the difference between @transaction and configuration @transaction (Propagation=propagation.supports) not configured?

In Common: there is no business.

The difference: The former does not enter the aspect, the latter enters the attempt to create a new session, open the transaction but not successful, will set a consent lazy loading session configuration. See the following code for details

4. When does Spring get the jdbcconnection setting from the thread pool Setautocommit (false)?

Body parsing:

Spring is the processing of @transactional annotations complete in the Createtransactionifnecessary method of Transactionaspectsupport (tangent programming). Then entrust the gettransaction () method to the Platformtransactionmanager implementation class (implementing

Class is Hibernatetransactionmanager is configured in application.xml) the processing of Propagation=propagation.supports is also implemented within this method, The details are in the parent class abstractplatformtransactionmanager.gettransaction ().

Code snippets such as the following:

Abstractplatformtransactionmanager.gettransaction (transactiondefinitiondefinition) {

Object Transaction = Dogettransaction (); // Note the Hibernatetransactionobject instance of 1:springframework, internally held by Hibernatesession, is null at the beginning;

. . Othercode. .

//No existing transaction found, check Propagationbehavior to find out how to proceed.

if (Definition.getpropagationbehavior () = = Transactiondefinition.propagation_mandatory) {

throw new Illegaltransactionstateexception (

"No existing transaction found for transactionmarked with propagation ' mandatory '");

}

Else if (Definition.getpropagationbehavior () = = Transactiondefinition.propagation_required | |

Definition.getpropagationbehavior () ==transactiondefinition.propagation_requires_new | |

Definition.getpropagationbehavior () ==transactiondefinition.propagation_nested) {

Suspendedresourcesholder suspendedresources = suspend (null);

if (debugenabled) {

Logger.debug ("Creating new transaction Withname [" + definition.getname () + "]:" + definition);

}

Try {

boolean newsynchronization = (gettransactionsynchronization ()! = Synchronization_never);

Defaulttransactionstatus status = Newtransactionstatus (

Definition, transaction, True, Newsynchronization, debugenabled, suspendedresources);

Dobegin (transaction, definition); // NOTE 2: Generate Hibernatesession, then get jdbcconnection, and Connection,setautocommit (false), Open the SQL transaction on our understanding. In detail, call the session holding hibernatejdbctransaction in the. Begin () method,

Preparesynchronization (status,definition); Set springtransactionsynchronizationmanager.initsynchronization ().

return status;

}

Catch (RuntimeException ex) {

Resume (null, suspendedresources);

throw ex;

}

Catch (Error Err) {

Resume (null, suspendedresources);

throw err;

}

}

Else {

// Note 3 This process is the path that runs when "there is no transaction in the thread and the configuration is propagation= propagation.supports". This step does not generate Hibernate Session, JDBC Connection. But preparetransactionstatus() took one step, setting Springtransactionsynchronizationmanager.initsynchronization (). It is after this operation that we have the ability to later hibernate save or update, Agree to hibernate callback initialization when the Spring springsessioncontext generated hibernatesession, further from the connection pool to get jdbcconnection

//Create "Empty" Transaction:no actualtransaction, but potentially synchronization.

boolean newsynchronization = (gettransactionsynchronization () = = Synchronization_always);

return preparetransactionstatus (definition, null, true, Newsynchronization, debugenabled, null);

}

. . .

}

Note 2 and note 3 answer 2, 3 questions.

A little bit of the idea of naming in the above code:

L Gettransaction return to Transactiostaus, feel more appropriate or named Gettransactiostaus than Spring's current naming gettransaction Gettransactionifnecessa Ry is better, according to note 3, this branch does not really open the database transaction. Not even get JDBC Connection. And no matter what the Hibernate Session is generated.

L A few of the more important classes springframework the jdbctransaction of the Hibernatetransactionobject,hibernate session,hibernate, The connection of JDBC. Springframework Hibernatetransactionobject holds a hibernate session, Hibernate session holds a hibernate jdbctransaction, Finally holds the JDBC Connection.

Because the database transaction Connection.setautocommit (FALSE). Transaction opening is attached to connection. The connection should be open before the transaction. So it feels different to use springframework Hibernatetransactionobject and hibernate jdbctransaction to hold JDBC connection.

Named Springframework Hibernatetransactionstatusobject, Hibernate jdbctransactionstaus more reasonable.

For a 4th question.

for @Transaction (Propagation=propagation.require) both the new session and session acquisition are completed in the abstractplatformtransactionmanager.gettransaction method.

For @transaction (propagation=propagation.supports), lazy when lazy gets the session, and only when the database operation is actually attempted Gets the connection.

Get a simple stack of connection such as the following.

ConnectionManager. Open Connection () line:446 // Note: Find no connection, get a connection from the thread pool

Connectionmanager.getconnection () line:167

Batchingbatcher (Abstractbatcher). Preparequerystatement (String,boolean, Scrollmode) line:161

Entityloader (Loader). Preparequerystatement (Queryparameters,boolean, Sessionimplementor) line:1700

Problem:

Two. For an extension of the 3rd minor problem above, note 3 indicates that no session is generated here. Then get or save normal without error. We define it as a case.

A. When in Propagation=propagation.supports, the session is not generated and gets to the JDBC Connection. When we save or get the normal error.

Here's a second case of getting a session without a session:

B. We may have encountered this error :No Hibernate Session bound to Thread,and configuration does not allow Creationof non-tr Ansactional one here. The cause of the error is that we don't get the session when we save or get, and it's not normal to throw the wrong

A and B are all in the absence of a session to get the session, why a normal, an abnormal?

Body parsing:

Detailed code snippets such as the following:

Springsessionfactoryutils.dogetsession (Sessionfactory Sessionfactory,interceptorentityinterceptor, Sqlexceptiontranslator jdbcexceptiontranslator,booleanallowcreate) {

if (Transactionsynchronizationmanager. issynchronizationactive ()) { /// Note 4: A case return is true, the reason is shown in Note 3, and the return is falsein case B.

                             //  Note :  This part of the code implements the " let's say no now . Session then you build Session " the logic

}

if ((! (allowcreate)) && (!) ( Issessiontransactional (session,sessionfactory))) { /// Note 5: two switches inferred. Allowcreate  For Hibernatemanager is mandatory set to false (off) , which is turned on (return true) when hibernatemanager processing @transaction. There was a consent to return the session to normal operation. Two have an open (ture) to not throw the wrong, normal run back to Session.

When is allowcreate a ture?

See below three. When can I get a session with a non-transactional type?

closesession (session);

throw new IllegalStateException ("No Hibernate Session bound to thread, Andconfiguration does isn't allow creation of NON-TRANSACTI Onalone Here ");

}

return session; // Note 6, assuming that no Note 5 is forbidden, then the generated Session is returned

}

Note 4, note 5 answers the above questions.

So there's a b problem , check your code, whether it's in a transactional environment. because Gettransaction () binds the session to Threadlocal , assuming that a new stand-alone thread is created, note that the internally called code is added @transaction, Otherwise, the thread is unable to get to the threadlocal session variable.

For this exception, the detailed semantics of the "configuration does Notallow creation of non-transactionalone here" in the latter part. " The configuration does not agree to generate a session of a non-transactional type. "

Three. When can I get a non-transactional type of session?

1. Viewing the source code can be found in the Opensessioninviewfilter (configured in Web. xml), it is this allow=true, so that it in a non-transactional environment, Sir into a session, and delayed shutdown. The view layer is guaranteed to get lazy loaded entities.

2. There is also the Hibernatetemplate Template tool class provided by spring which is also allow=true, which allows us to run the Hibernate method.

Other such as Propagation= Propagation.require_new is also in the above code, the original connection suspend and resume operation. See the code for details.

Other such as propagation =propagation.require_new is also in the above code, the original connection suspend and resume operation. See the code for details.

Copyright notice: This article Bo Master original articles, blogs, without consent may not be reproduced.

[principle] [source parsing]spring in @transactional,propagation.supports, and Hibernate Session, and JDBC Connection Association

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.