Principle [Source code parsing]spring @transactional,propagation.supports, and Hibernate Session, and JDBC Connection relationship---Reprint

Source: Internet
Author: User

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 1:springframework's Hibernatetransactionobject instance, 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() Does a step, setting springtransactionsynchronizationmanager.initsynchronization (). It is only after this operation that we are able to allow Hibernate callback to initialize the Spring Springsessioncontext generated hibernatesession when hibernate save or update occurs, Further getting 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), session new and session acquisition are The Abstractplatformtransactionmanager.gettransaction method completes the

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

The simple stack that gets connection is as follows.

Connectionmanager.openconnection () 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 let Creationof non-transactional one here. Wrong Wrong reason is that we do not get the session when we save or get, abnormal error

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 logic of "generate sessionif no session is present"

}

if ((! (allowcreate)) && (!) ( Issessiontransactional (session,sessionfactory))) {/// Note 5: two switches judged. Allowcreate is mandatory for Hibernatemanager is set to false (off) , which is turned on when hibernatemanager processing @transaction is preceded (  Returns True). 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-transactional one 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.

Original address: http://blog.csdn.net/fei33423/article/details/32346821

[principle] [Source code parsing]spring @transactional,propagation.supports, and Hibernate Session, and JDBC Connection relationship---reprint

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.