HibernateTransactionManager对事务的实现,最终都是通过处理hibernate的Transaction的commit,rollback方法完成,
与单独的hibernate的Transaction事务没有太大的区别;但是,HibernateTransactionManager通过注入sessionfactory.
然后在得到session,把session包装成SessionHolder(),并通过threadlocal来对象的实现和线程的绑定(threadlocal实现重点)
最后到线程中的session取得的Transaction,
//SessionHolder对session包装,绑定到threadlocal中去
private final Map<Object, Session> sessionMap = Collections.synchronizedMap(new HashMap<Object, Session>(1));
1.主要理解这个类的doBegin(),doGetTransaction()方法
protected void doBegin(Object transaction, TransactionDefinition definition)
doBegin(Object transaction, TransactionDefinition definition)负责事务的创建
两个参数:
第一个参数:Object transaction
会得到session和一个connection.
设置HibernateTransactionObject,获取线程中的session和connectionprotected Object doGetTransaction() {
//这是一个SPI类,代表一个SessionHolder
HibernateTransactionObject txObject = new HibernateTransactionObject();
//在事务中设置保存点,是否允许嵌套事务
txObject.setSavepointAllowed(isNestedTransactionAllowed());
//在绑定的线程中查找当前的session,SessionHolder是session的包装,SessionHolder绑定到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) {
.......
}
}
//得到一个connection,它也是和线程绑定的
if (getDataSource() != null) {
ConnectionHolder conHolder = (ConnectionHolder)
TransactionSynchronizationManager.getResource(getDataSource());
txObject.setConnectionHolder(conHolder);
}
return txObject;
}
事务开始的地方
protected void doBegin(Object transaction, TransactionDefinition definition) {
HibernateTransactionObject txObject = (HibernateTransactionObject) transaction;
if (txObject.hasConnectionHolder() && !txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
throw new IllegalTransactionStateException(
......
Session session = null;
//如果SessionHolder没有被创建,那么这里openSession并放到SessionHolder中去
try {
if (txObject.getSessionHolder() == null || txObject.getSessionHolder().isSynchronizedWithTransaction()) {
Interceptor entityInterceptor = getEntityInterceptor();
Session newSession = (entityInterceptor != null ?
getSessionFactory().openSession(entityInterceptor) : getSessionFactory().openSession());
if (logger.isDebugEnabled()) {
......
}
txObject.setSession(newSession);
}
//三种得到session(OpenSessionInView,getcurrentsession,opensession),这里就从SessionHolder得到session
session = txObject.getSessionHolder().getSession();
//设置<tx>isolation,read-only属性
if (this.prepareConnection && isSameConnectionForEntireSession(session)) {
// We're allowed to change 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 this transaction.
session.setFlushMode(FlushMode.MANUAL);
}
if (!definition.isReadOnly() && !txObject.isNewSession()) {
// We need AUTO or COMMIT for a non-read-only 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 Hibernate 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.
//创建并开始事务
hibTx = session.beginTransaction();
}
// Add the Hibernate transaction to the session holder.
//把hibtx事务放到txobject里面,原因是因为这个SessionHolder会和线程绑定
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.
//如果是新的SessionHolder,把它和线程绑定
if (txObject.isNewSessionHolder()) {
TransactionSynchronizationManager.bindResource(getSessionFactory(), txObject.getSessionHolder());
}
//SessionHolder的状态标识,你的Transaction是一个线程中的session取得的
txObject.getSessionHolder().setSynchronizedWithTransaction(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);
}
}