多線程與hibernate openSession綁定在當前線程

先上代碼:

package com.ifunpay.portal.task;

import com.alibaba.fastjson.JSON;
import com.ifunpay.portal.dao.order.OrderEntityDao;
import com.ifunpay.portal.entity.order.OrderEntity;
import com.ifunpay.portal.model.PaidInfo;
import com.ifunpay.portal.service.PaymentManageService;
import com.ifunpay.portal.service.payment.AbcAggPaymentManager;
import com.ifunpay.util.enums.BankAppEnum;
import com.ifunpay.util.enums.PaymentStatusEnum;
import lombok.extern.log4j.Log4j2;
import org.hibernate.FlushMode;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.orm.hibernate4.SessionFactoryUtils;
import org.springframework.orm.hibernate4.SessionHolder;
import org.springframework.stereotype.Component;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.web.servlet.ModelAndView;

import java.util.Map;


/**
 * @Author: lilong
 * @Data: Created on 2019/12/3
 * @Desc: 線程池
 */
@Log4j2
@Component
public class AbcAggTask implements Runnable {
    public static final String SUCCESS  = "SUCCESS";

    private  PaymentManageService paymentManageService;

    private OrderEntityDao orderEntityDao;

    private ApplicationContext applicationContext;

    protected String orderId;
    protected String commercialId;
    protected String privateKey;

    public AbcAggTask(String commercialId,String orderId,String privateKey,OrderEntityDao orderEntityDao,PaymentManageService paymentManageService,ApplicationContext applicationContext) {
        this.commercialId = commercialId;
        this.orderId = orderId;
        this.privateKey = privateKey;
        this.orderEntityDao = orderEntityDao;
        this.paymentManageService = paymentManageService;
        this.applicationContext = applicationContext;
    }

    @Override
    public void run() {
        SessionFactory sessionFactory = null;
        boolean participate = false ;
        try {
            //重點在這兩行代碼~綁定session到當前線程 
            sessionFactory = (SessionFactory)applicationContext.getBean("sessionFactory");
            participate = bindHibernateSessionToThread(sessionFactory);
            //業務邏輯代碼
            OrderEntity order = orderEntityDao.findByOrderId(orderId);
            if (PaymentStatusEnum.NotPay.equals(order.getPaymentStatus())) {
                log.info("abcAggCallBackIsNull...query....orderId:"+orderId);
                for (int i = 1; i < 21; i++) {
                    if (i == 1) {
                        Thread.sleep(30000);
                    } else {
                        Thread.sleep(5000);
                    }
                    AbcAggPaymentManager abcAggPaymentManager = new AbcAggPaymentManager();
                    String result = abcAggPaymentManager.query(commercialId, orderId, privateKey);
                    Map<String,String> returnMap = JSON.parseObject(result,Map.class);
                    if (SUCCESS.equals(returnMap.get("code")) && SUCCESS.equals(returnMap.get("trade_state"))){ //訂單支付成功
                        ModelAndView modelAndView = new ModelAndView();
                        modelAndView.setViewName("payment/callback");
                        PaidInfo paidInfo = new PaidInfo();
                        paidInfo.setModelAndView(modelAndView);
                        paidInfo.setBank(BankAppEnum.ABCAGG);
                        paidInfo.setAmount(order.getTotalAmount());
                        paidInfo.setStatus(PaymentStatusEnum.PaySucceeded);
                        paidInfo.setOrderId(order.getCode());
                        paidInfo.setPosId(null);
                        paidInfo.setSerialNumber(returnMap.get("transaction_id"));
                        paidInfo.getModelAndView().setViewName("error");
                        paymentManageService.notifyCallbackObservers(paidInfo);
                        break;
                    }else {
                        log.error("getAbcAggQrcodeFiled...:code:"+returnMap.get("code")+";message:"+returnMap.get("message"));
                    }
                }
            }
        } catch (Exception e) {
            log.error("abcAggTaskFailed:", e);
        }finally {
            //關閉Session
            closeHibernateSessionFromThread(participate,sessionFactory);
        }
    }

    /**
 * @Author: lilong
 * @Data: Created on 2019/12/3
 * @Desc: open一個session然後將其綁定在當前線程
 */
    public static boolean bindHibernateSessionToThread(SessionFactory sessionFactory){
        if (TransactionSynchronizationManager.hasResource(sessionFactory)){
            return true;
        }else {
            Session session = sessionFactory.openSession();
            session.setFlushMode(FlushMode.MANUAL);
            SessionHolder sessionHolder = new SessionHolder(session);
            TransactionSynchronizationManager.bindResource(sessionFactory,sessionHolder);//將open的session 綁定帶線程
        }
        return false;
    }

        /**
 * @Author: lilong
 * @Data: Created on 2019/12/3
 * @Desc: open的session都要手動關閉
 */

    public static void closeHibernateSessionFromThread(boolean participate,Object sessionFactory){
        if (!participate){
            SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.unbindResource(sessionFactory);
            SessionFactoryUtils.closeSession(sessionHolder.getSession());
        }
    }
}

先了解下這個~~~openSession()和getCurrentSession的區別,然後看代碼!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章