package com.mandi.dao.common;

import org.apache.log4j.Logger;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;

/**
 * @author mengly
 * @version 创建时间:2016年7月4日 上午11:23:28 类说明
 * 
 */

public class TransactionContext {
	private Logger log = Logger.getLogger(TransactionContext.class);

	public enum Status {
		none, started, commit, rollback
	};

	public enum TranResult {
		none, notCommit, commitOK, rollback, commitNoDone
	}

	public enum Trantype {
		func, service
	}

	private Status status = Status.none;
	private TranResult result = TranResult.none;
	private Transaction transaction = null;
	private Session session = null;
	private int sCount = 0;
	private SessionFactory sf;

	public TransactionContext(SessionFactory sf) {
		this.sf = sf;
	}
	public Session getsession() {
		if (session != null && session.isOpen() && session.isConnected()
				&& Daomethod.checksession(session)) {
			return session;
		}
		this.session = sf.openSession();
		return session;
	}
	public Status checkStatus() {
		return status;
	}

	public TranResult checkResult() {
		return result;
	}

	public Transaction getTransaction() {
		return transaction;
	}

	public void setTransaction(Transaction transaction) {
		this.transaction = transaction;
	}

	public Status startTran() {
		this.session = this.getsession();
		this.transaction = session.getTransaction();
		if(sCount>0){
			if (this.transaction != null && this.transaction .isActive()) {
				sCount++;
				return status;
			}
		}
		sCount = 0;// 如果是sCount小于0的话调整为0
		try {
			this.transaction = session.beginTransaction();
			if (transaction != null) {
				sCount++;
				this.status = Status.started;
				return this.status;
			}
		} catch (Exception e) {
			e.printStackTrace();
			transaction = null;
			this.status = Status.none;
			this.close();
		}
		return Status.none;
	}
	/**
	 * 强制提交
	 * @return 
	 * @author mengly 
	 * @version 创建时间:2016年10月22日 下午12:17:27
	 */
	public TranResult commitF(){
		if (this.session == null || !this.session.isOpen()) {
			result = TranResult.none;
			sCount = 0;
			return result;
		}
		try{
			this.transaction=this.session.getTransaction();
			this.transaction.commit();
			return TranResult.commitOK;
		}catch(Exception e){
			this.transaction.rollback();
			return TranResult.rollback;
		}finally{
			transaction=null;
			sCount = 0;
		}
	}
	public TranResult commit() {
		if (this.session == null || !this.session.isOpen()) {
			result = TranResult.none;
			sCount = 0;
			return result;
		}
		this.transaction=this.getsession().getTransaction();
			sCount--;
			if (sCount <= 0) {
				try {
					if (this.transaction != null) {
						this.transaction.commit();
						this.status = Status.commit;
					}
					this.transaction = null;
					return TranResult.commitOK;
				} catch (Exception e) {
					e.printStackTrace();
//					if (this.transaction != null) {
//						this.transaction.rollback();
//						this.transaction = null;
//					}
					return TranResult.rollback;
				} finally {
					this.close();
				}
			} else {
				return TranResult.commitNoDone;
			}
	}

	public int getSCount(){
		return this.sCount;
	}
	public TranResult rollback() {
		this.transaction=this.getsession().getTransaction();
			try {
				if(this.transaction!=null)
					this.transaction.rollback();
				this.transaction = null;
				this.status = Status.rollback;
				this.sCount = 0;
				return TranResult.rollback;
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				this.sCount = 0;
				this.transaction = null;
				this.close();
			}
		return result;
	}

	public void close() {
		if (this.session != null) {
			try {
				this.status = Status.none;
				this.transaction=this.session.getTransaction();
				if(transaction!=null&&transaction.isActive()){
					transaction.rollback();
				}
				this.sCount = 0;
				this.transaction = null;
				session.close();
			} catch (Exception e) {
				this.sCount = 0;
				this.transaction = null;
				session.close();
			}
		}
	}
}