package com.palmnest.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;


/**
 * 保存或者更新数据线程
 *
 * @author yb
 * @date 2014-04-14
 */
@Slf4j
@Component("asynchronousDataService")
public class AsynchronousDataService implements Runnable {


	private ExecutorService executeService;

	private static final int defaultThreadCount = 4;

	private LinkedBlockingQueue<Executable> msgs = new LinkedBlockingQueue<Executable>();

	@Resource
	private TransactionDefinition      transactionDefinition;
	@Qualifier("transactionManager")
	@Resource
	private PlatformTransactionManager transactionManager;

	@PostConstruct
	public void init() {
		log.info("Executors pool init.");
		executeService = Executors.newFixedThreadPool(defaultThreadCount);
		for (int i = 0; i < defaultThreadCount; i++) {
			executeService.execute(this);
		}
	}

	public void store(Executable msg) {
		msgs.add(msg);
	}

	@Override
	public void run() {
		while (true) {
			try {
				Executable msg;
				msg = msgs.take();
				if (msg == null) {
					continue;
				}
				log.debug("execute job.{}", msg);
				//开启事物
				TransactionStatus transactionStatus = transactionManager.getTransaction(transactionDefinition);
				try {
					msg.execute();
					transactionManager.commit(transactionStatus);
					log.debug("执行数据库操作成功");
				} catch (Exception e) {
					transactionManager.rollback(transactionStatus);
					log.error("发生数据库异常", e);
				}
			} catch (InterruptedException e) {
				log.error("执行插入数据线程发生错误 {} ", e, e.getMessage());
			}
		}
	}

}
