Hibernatetransactionmanager's implementation of the transaction is ultimately done by processing hibernate's transaction Commit,rollback method,
There is not much difference between transaction transactions with separate hibernate, but hibernatetransactionmanager by injecting sessionfactory.
Then in the session, the session is packaged into Sessionholder (), and the implementation of the object through threadlocal and thread binding (threadlocal to achieve the focus)
Finally to the session in the thread to get the transaction,
Sessionholder to the Session wrapper, bound to the threadlocal to the
private final map<object, session> sessionmap = Collections.synchronizedmap (New Hashmap<object, session> (1));
1. The main understanding of this class of Dobegin (), Dogettransaction () method
protected void Dobegin (Object transaction, transactiondefinition definition)
Dobegin (Object transaction, transactiondefinition definition) is responsible for the creation of transactions
Two parameters:
First parameter: Object transaction
Will get a session and a connection. Set Hibernatetransactionobject to get the session and connection in the thread
Protected Object dogettransaction () {///This is an SPI class that represents a sessionholder hibernatetransactionobject txobject = new Hibernate
Transactionobject ();
Sets the savepoint in the transaction, whether to allow nested transactions txobject.setsavepointallowed (isnestedtransactionallowed ()); Find the current session,sessionholder in the bound thread is the wrapper for the session, Sessionholder bound to threadlocal sessionholder Sessionholder = (
Sessionholder) Transactionsynchronizationmanager.getresource (Getsessionfactory ());
if (Sessionholder! = null) {... txobject.setsessionholder (sessionholder);
} else if (this.hibernatemanagedsession) {try {session session = Getsessionfactory (). Getcurrentsession ();
.... txobject.setexistingsession (session);
} catch (Hibernateexception ex) {...} }//Get a connection, which is also a thread-bound if (Getdatasource ()! = null) {Connectionholder Conholder = (connectionh
Older) Transactionsynchronizationmanager.getresource (Getdatasource ()); Txobject.setconnectionholder (Conholder);
} return txobject; }
Where the transaction started
protected void Dobegin (Object transaction, transactiondefinition definition) {hibernatetransactionobject Txobject = (Hi
Bernatetransactionobject) transaction;
if (Txobject.hasconnectionholder () &&!txobject.getconnectionholder (). Issynchronizedwithtransaction ()) {
throw new Illegaltransactionstateexception (...)
Session session = NULL; If Sessionholder is not created, then this is opensession and put in Sessionholder. try {if (txobject.getsessionholder () = NULL | | txobject.ge
Tsessionholder (). Issynchronizedwithtransaction ()) {Interceptor Entityinterceptor = Getentityinterceptor ();
Session newsession = (Entityinterceptor! = null?)
Getsessionfactory (). Opensession (Entityinterceptor): Getsessionfactory (). Opensession ());
if (logger.isdebugenabled ()) {...}
Txobject.setsession (newsession); }//Three to get the session (Opensessioninview,getcurrentsession,opensession), here to get the session session from Sessionholder = Txobject.getsessionholder (). getsession(); Set the <tx>isolation,read-only property if (this.prepareconnection && issameconnectionforentiresession (session
) {//We ' re allowed to the transaction settings of the JDBC Connection.
......
Connection con = session.connection ();
Integer previousisolationlevel = datasourceutils.prepareconnectionfortransaction (con, definition);
Txobject.setpreviousisolationlevel (Previousisolationlevel);
} else {//not allowed to change the transaction settings of the JDBC Connection.
......
} if (definition.isreadonly () && txobject.isnewsession ()) {//Just set to never in case of a new Session for th
is transaction.
Session.setflushmode (flushmode.manual); } if (!definition.isreadonly () &&!txobject.isnewsession ()) {//We need AUTO or COMMIT for a non-read-onl
Y transaction.
Flushmode Flushmode = Session.getflushmode (); if (Flushmode.lessthan (Flushmode.commit)) {Session.setflushmode (FlushmoDe.
AUTO);
Txobject.getsessionholder (). Setpreviousflushmode (Flushmode);
}} Transaction HIBTX;
Register transaction Timeout.
int timeout = determinetimeout (definition); if (timeout! = Transactiondefinition.timeout_default) {//Use Hibernate ' s own transaction timeout mechanism on Hibern
Ate 3.1+//applies to all statements, also to inserts, updates and deletes!
HIBTX = Session.gettransaction ();
Hibtx.settimeout (timeout);
Hibtx.begin ();
} else {//Open a plain Hibernate transaction without specified timeout.
Create and start transaction HIBTX = Session.begintransaction ();
}//Add the Hibernate transaction to the session holder.
Put the HIBTX transaction inside the Txobject because the Sessionholder will be bound to the thread Txobject.getsessionholder (). Settransaction (HIBTX);
Register the Hibernate Session ' s JDBC Connection for the DataSource, if set. if (getdatasource () = null) {Connection con = Session.connection ();
Connectionholder Conholder = new Connectionholder (con);
if (timeout! = Transactiondefinition.timeout_default) {conholder.settimeoutinseconds (timeout); } if (logger.isdebugenabled ()) {Logger.debug ("Exposing Hibernate transaction as JDBC transaction [" + Con + "]")
;
} transactionsynchronizationmanager.bindresource (Getdatasource (), conholder);
Txobject.setconnectionholder (Conholder);
}//Bind the session holder to the thread. If it is a new sessionholder, bind it and thread if (Txobject.isnewsessionholder ()) {Transactionsynchronizationmanager.bindresource (g
Etsessionfactory (), Txobject.getsessionholder ()); }//sessionholder Status ID, your transaction is a thread in the session obtained by Txobject.getsessionholder (). Setsynchroniz
Edwithtransaction (TRUE);
} catch (Exception ex) {if (Txobject.isnewsession ())} {try {if (session.gettransaction (). IsActive ()) {
Session.gettransaction (). rollback ();
} } catch (Throwable ex2) {logger.debug ("Could not rollback Session after failed transaction begin", ex);
} finally {sessionfactoryutils.closesession (session);
}} throw new Cannotcreatetransactionexception ("Could not open Hibernate Session for Transaction", ex);
}
}