Spring HibernateTransactionManager 사물 관리 클래스 (HibernateTransactionObject)
public class HibernateTransactionManager extends AbstractPlatformTransactionManager
implements ResourceTransactionManager, BeanFactoryAware, InitializingBean {
우선 이 종 류 는 AbstractPlatformTransactionManager 류 를 계승 하고 일련의 인 터 페 이 스 를 실현 했다.
public abstract class AbstractPlatformTransactionManager implements PlatformTransactionManager, Serializable {
AbstractPlatformTransactionManager 라 는 추상 적 인 종 류 는 인터페이스의 getTransaction (TransactionDefinition definition definition) 방법 을 실 현 했 습 니 다. 이 방법 에서 doGetTransaction (), doBegin () 방법 과 다른 방법 을 실 행 했 습 니 다. 여기 서 일일이 소개 하지 않 겠 습 니 다.
하위 클래스 인 HibernateTransactionManager 클래스 로 돌아 가면 부모 클래스 의 doGetTransaction () 방법 과 doBegin (), doCommit () 을 다시 썼 습 니 다. 그래서 이 방법 이 우리 가 주로 토론 해 야 할 것 입 니 다. 그리고 doCommit ()...
부모 클래스 의 getTransaction (TransactionDefinition definition definition) 을 보면 먼저 doGetTransaction () 을 한 다음 doBegin () 을 걷는다.
doGetTransaction () 방법 소스 코드 를 살 펴 보 겠 습 니 다.
protected Object doGetTransaction() {
HibernateTransactionObject txObject = new HibernateTransactionObject();// new HibernateTransactionObject
txObject.setSavepointAllowed(isNestedTransactionAllowed());//
// sessionFacoty key sessionHolder,
SessionHolder sessionHolder =
(SessionHolder) TransactionSynchronizationManager.getResource(getSessionFactory());
if (sessionHolder != null) {
if (logger.isDebugEnabled()) {
logger.debug("Found thread-bound Session [" +
SessionFactoryUtils.toString(sessionHolder.getSession()) + "] for Hibernate transaction");
}
txObject.setSessionHolder(sessionHolder);// sessionHolder txObject
}
else if (this.hibernateManagedSession) {// , thread, Spring
try {
Session session = getSessionFactory().getCurrentSession();//
if (logger.isDebugEnabled()) {
logger.debug("Found Hibernate-managed Session [" +
SessionFactoryUtils.toString(session) + "] for Spring-managed transaction");
}
txObject.setExistingSession(session);// sessionHolder txObject , set session
}
catch (HibernateException ex) {
throw new DataAccessResourceFailureException(
"Could not obtain Hibernate-managed Session for Spring-managed transaction", ex);
}
}
// DataSource, afterPropertiesSet() sessionFactory DataSource
if (getDataSource() != null) {
ConnectionHolder conHolder = (ConnectionHolder)
TransactionSynchronizationManager.getResource(getDataSource());// , doBegin()
txObject.setConnectionHolder(conHolder);// sessionHolder txObject
}
return txObject;
}
위 에 있 는 doGetTransaction () 방법 이 끝나 면 HibernateTransactionObject txObject 대상 을 만 들 었 습 니 다. 이 대상 도 주인공 이 고 이 대상 에 두 개의 속성 을 채 워 서 이 두 속성 에 값 을 부여 합 니 다. 하 나 는 session holder 이 고 다른 하 나 는 connection Holder 입 니 다. 즉, session 과 connect 입 니 다.
업무 논리 에 있 는 C 방법 에 A, B 방법 이 포함 되 어 있 을 때 동시에 호출 됩 니 다. 하나의 사무 만 열 었 습 니 다. session 은 현재 스 레 드 에 있 는 것 과 같 습 니 다. session Factory Utils. dogetSession () 을 직접 뛰 었 습 니 다.
action 호출 을 분리 할 때 먼저 A 후 B 는 A 에 게 사 무 를 열 고 B 에 게 사 무 를 열 지만 스 레 드 에서 session 을 가 져 옵 니 다.
다음은 doBegin () 방법 입 니 다. 새로운 대상 TransactionDefinition 사물 설명 을 도입 하고 일부 코드 는 생략 합 니 다.
protected void doBegin(Object transaction, TransactionDefinition definition) {
HibernateTransactionObject txObject = (HibernateTransactionObject) transaction;// txObject , HibernateTransactionObject
// sessionHolder , hibernate session, session SessionHolder
Session session = null;
try {// txObject sessionHolder
if (txObject.getSessionHolder() == null || txObject.getSessionHolder().isSynchronizedWithTransaction()) {
Interceptor entityInterceptor = getEntityInterceptor();//
Session newSession = (entityInterceptor != null ?
getSessionFactory().openSession(entityInterceptor) : getSessionFactory().openSession());
if (logger.isDebugEnabled()) {
logger.debug("Opened new Session [" + SessionFactoryUtils.toString(newSession) +
"] for Hibernate transaction");
}
txObject.setSession(newSession);
}
// sessionHolder session, hibernateTransaction
session = txObject.getSessionHolder().getSession();
if (this.prepareConnection && isSameConnectionForEntireSession(session)) {
// We're allowed to change the transaction settings of the JDBC Connection.
if (logger.isDebugEnabled()) {
logger.debug(
"Preparing JDBC Connection of Hibernate Session [" + SessionFactoryUtils.toString(session) + "]");
}
Connection con = session.connection();
Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
txObject.setPreviousIsolationLevel(previousIsolationLevel);
}
else {
// Aop isolation
// Not allowed to change the transaction settings of the JDBC Connection.
if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) {
// We should set a specific isolation level but are not allowed to...
throw new InvalidIsolationLevelException(
"HibernateTransactionManager is not allowed to support custom isolation levels: " +
"make sure that its 'prepareConnection' flag is on (the default) and that the " +
"Hibernate connection release mode is set to 'on_close' (SpringTransactionFactory's default). " +
"Make sure that your LocalSessionFactoryBean actually uses SpringTransactionFactory: Your " +
"Hibernate properties should *not* include a 'hibernate.transaction.factory_class' property!");
}
if (logger.isDebugEnabled()) {
logger.debug(
"Not preparing JDBC Connection of Hibernate Session [" + SessionFactoryUtils.toString(session) + "]");
}
}
// Aop read-only ,
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()) {
// , session, session, true(OpenSessionView)
// 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) {
hibTx = session.getTransaction();
// , hibTx.begin();
hibTx.setTimeout(timeout);
}else {
// hibernate txObject sessionHolder , sessionHolder .
hibTx = session.beginTransaction();
}
// Transaction hibTx txObject , txObject ,
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);// connection
if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
conHolder.setTimeoutInSeconds(timeout);
}
if (logger.isDebugEnabled()) {
logger.debug("Exposing Hibernate transaction as JDBC transaction [" + con + "]");
}
// connection .
TransactionSynchronizationManager.bindResource(getDataSource(), conHolder);
// txObject ConnectionHolder , con null
txObject.setConnectionHolder(conHolder);
}
// sessionHolder, // Bind the session holder to the thread.
if (txObject.isNewSessionHolder()) {
// sessionHolder, false,open true
TransactionSynchronizationManager.bindResource(getSessionFactory(), txObject.getSessionHolder());
//
}
// sessionHolder , 。
txObject.getSessionHolder().setSynchronizedWithTransaction(true);
}
}
4. 567913. doCommit () 는 모두 가 사무 제출 이라는 것 을 알 고 있 습 니 다. 물론 제출 하기 전에 도 많은 일 을 했 습 니 다. 예 를 들 어 session 을 비 우 는 방법 은 일일이 열거 되 지 않 았 습 니 다. 부모 류 AbstractPlatformTransactionManager 의 processCommit () 방법 을 볼 수 있 습 니 다. prepareForCommit 를 먼저 뛰 어 제출 을 준비 하 는 방법 등 을 볼 수 있 습 니 다.
스 레 드 에 연 결 된 사무, rollback.
더 자세히 보기:
http://sailinglee.iteye.com/blog/598908
http://books.google.com.hk/books?id=jRVp2INtY1AC&pg=PA222&lpg=PA222&dq=HibernateTransactionManager#v=onepage&q=HibernateTransactionManager&f=false
TransactionDefinition:
http://book.51cto.com/art/200909/149403.htm
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.