Principle [Source code parsing]spring @transactional,propagation.supports, and Hibernate Session, and the JDBC connection relationship

Source: Internet
Author: User

Spring binds hibernate.

Directory:

One

1. How does Spring handle 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. How does the @transaction and configuration @transaction (propagation=propagation.supports) affect the generation session, what are the similarities and differences?

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 I get a non-transactional Session?

Problem:

One.

1. How does Spring handle 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 allows 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.

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 be set to allow lazy loading session configuration. See the code below 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 in the Createtransactionifnecessary method of Transactionaspectsupport (tangent programming). Then delegate 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, Specifically, the parent class abstractplatformtransactionmanager.gettransaction ().

The code snippet is as follows:

Abstractplatformtransactionmanager.gettransaction (transactiondefinitiondefinition) {

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

. . 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 that we understand. Specifically, call the hibernatejdbctransaction in the. Begin () method in the session holding

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 is executed 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 only after this operation that we can later hibernate save or update, Allows hibernate callback to be initialized when the Spring springsessioncontext generates hibernatesession and further gets jdbcconnection from the connection pool

//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 actually open the database transaction. Not even get JDBC Connection. And any generated Hibernate Session.

L Compare important Several classes of Springframework Hibernatetransactionobject,hibernate's session,hibernate jdbctransaction, The connection of JDBC. Springframework Hibernatetransactionobject holds a hibernate session, Hibernate session holds a hibernate jdbctransaction, Eventually 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 done 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.

The simple stack that gets connection is as follows.

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 another scenario where you can get 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-t Ransactional 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:

The specific code snippet is as follows:

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 " If there is no Session then you build Session " the logic

}

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

When allowcreate is ture? See below three. When can I get a session of 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, if no Note 5 is prohibited, 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. since gettransaction () binds the session to Threadlocal , if a new independent thread is created, note whether the code inside the call is added @transaction, Otherwise, the thread is unable to get to the threadlocal session variable.

For this exception, the specific semantics of the "configuration does Notallow creation of non-transactionalone here" in the latter part. means " Configuration does not allow a session with a non-transactional type to be generated. "

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

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

2. There is also the Hibernatetemplate Template tool class provided by spring which is also allow=true, which allows us to execute 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.

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.