`
8366
  • 浏览: 815538 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

公司一大牛写的一个自动任务框架

阅读更多

有一种人,徘徊在牛a和牛c之间。。。

 

 在工作中经常有业务是异步的:

1.用户办了一个订单,填写了一个反馈,当订单竣工的时候要发短信通知客户,说你办理的业务现在成功了

2.用户定购了一个账单,要每个月都要给用用户发送 上月用户账单内容到指定的 邮箱 或者 手机

3.有些统计的内容 需要每天计算 插到数据库里

 

等等,这都需要有个自动任务来管理,定时执行这些任务,并且统一管理。

 

公司一牛人写了一个自动任务的框架,可以定时帮助我们执行一些任务,并且由一张表(neb_trigger)统一管理,在工作中我们就是使用的 这个自动任务的框架 来完成 某些异步业务 或者定时任务的

 

 

我们项目的架构 是前台的action调用 后台的ejb ,因此自动任务 写在ejb里,大致的原理如下:

 

1.首先 自动任务(Trigger)维护着 一张表 (netb_trigger),她根据表中任务的信息,来执行业务方法(利用反射),表中有个字段是 业务方法的实现类的

 

2.定义了一个接口 TriggerTask ,只有一个方法 doTask(),何使用到自动任务的 业务都需要实现这个接口

 

3.Trigger 是一个会话bean ,其实现方法只有 一个业务方法 runTask(),它会调用 TriggerTask 接口中的runTask()方法 利用反射来执行 业务方法

 

4.为了对 netb_trigger 进行 添加,修改,删除 自动任务,又写了一个 TriggerManage类,这个类是用来供Action层来添加删除和修改自动任务的,其中有个方法

 public static String addTask(
   String taskDesc,
   String clazz,
   String inParam,
   String cycle,
   String cycleLimit,
   String dayLimit,
   String hourLimit) throws Exception

 

自动任务将 利用 传递的clazz 来 反射调用业务方法

 

目标:通过 一个main方法去 掉部署在jboss的ejb的自动任务,然他去定时执行执行业务方法

 

为了让大家能使用到这个自动任务框架 我一步一步 让这个自动任务跑起来!!flow me,let's go!!

 

首要条件:需要有jboss ,hibernate,mysql 环境

 

步骤1:建立 自动任务状态表,以及对应的实体

任务表:netb_trigger

Sql代码 复制代码
  1. CREATE TABLE `netb_trigger` (              
  2.                 `ID` char(255) NOT NULL,                 
  3.                 `TASKDESC` char(255) DEFAULT NULL,       
  4.                 `STATE` int(10) DEFAULT NULL,            
  5.                 `CLAZZ` char(255) DEFAULT NULL,          
  6.                 `INPARAM` char(255) DEFAULT NULL,        
  7.                 `CYCLE` char(255) DEFAULT NULL,          
  8.                 `CYCLELIMIT` char(255) DEFAULT NULL,     
  9.                 `DAYLIMIT` char(255) DEFAULT NULL,       
  10.                 `HOURLIMIT` char(255) DEFAULT NULL,      
  11.                 `CREATETIME` datetime DEFAULT NULL,      
  12.                 `LASTTIME` datetime DEFAULT NULL,        
  13.                 PRIMARY KEY (`ID`)                       
  14.               ) ENGINE=InnoDB DEFAULT CHARSET=gbk       
CREATE TABLE `netb_trigger` (           
                `ID` char(255) NOT NULL,              
                `TASKDESC` char(255) DEFAULT NULL,    
                `STATE` int(10) DEFAULT NULL,         
                `CLAZZ` char(255) DEFAULT NULL,       
                `INPARAM` char(255) DEFAULT NULL,     
                `CYCLE` char(255) DEFAULT NULL,       
                `CYCLELIMIT` char(255) DEFAULT NULL,  
                `DAYLIMIT` char(255) DEFAULT NULL,    
                `HOURLIMIT` char(255) DEFAULT NULL,   
                `CREATETIME` datetime DEFAULT NULL,   
                `LASTTIME` datetime DEFAULT NULL,     
                PRIMARY KEY (`ID`)                    
              ) ENGINE=InnoDB DEFAULT CHARSET=gbk     

 

 实体Tirgger

 

Java代码 复制代码
  1. package cn.com.xinli.netb.entitys;   
  2.   
  3. import java.io.Serializable;   
  4. import java.sql.Timestamp;   
  5.   
  6. /**  
  7.  *  触发任务表  
  8.  * @author diaoyf  
  9.  *  
  10.  */  
  11. public class Trigger implements Serializable   
  12. {   
  13.     public static final long serialVersionUID = 1;   
  14.        
  15.     /** id */  
  16.     private String id;   
  17.        
  18.     /** 触发任务描述 */  
  19.     private String taskDesc;   
  20.        
  21.     /** 触发状态 0:允许触发 1:取消触发 */  
  22.     private int state;   
  23.        
  24.     /**  
  25.      * 回调对象的包、类路径名  
  26.      * 触发管理器根据此包、类路径名,通过反射机制实例化对象  
  27.      */  
  28.     private String clazz;   
  29.     /** 回调方法输入参数 */  
  30.     private String inParam;   
  31.   
  32.     /**  
  33.      * 触发周期  
  34.      * <li>atonce 表示一次(由小时触发器管理)</li>  
  35.      * <li>min 表示每分</li>  
  36.      * <li>hour 表示每小时</li>  
  37.      * <li>day 表示每天</li>  
  38.      * <li>month 表示每月</li>  
  39.      * <li>3month 表示每季度</li>  
  40.      * <li>year 表示每年</li>  
  41.      */  
  42.     private String cycle;   
  43.        
  44.     /**  
  45.      *  触发时间限制  
  46.      *  格式"2007/10/2 8:15:28-2007/10/3 18:15:30",表示任务存在时间  
  47.      *  格式"-", 表示无触发时间限制  
  48.      *    
  49.      */  
  50.     private String cycleLimit;    
  51.     /**  
  52.      * 触发日期限制  
  53.      * 如月账单反馈限制在每月10~15日(包括15日),dayLimit设置格式为"10-15";  
  54.      * 如限制在每月10日,设置格式为"10-10";  
  55.      * 如果没有日期限制,设置格式为"-"  
  56.      * 如果起始日期大于终止日期,如"25-10",表示当月25日到下月10日  
  57.      */  
  58.     private String dayLimit;    
  59.     /**  
  60.      * 触发时间限制,时间规则最小"00:00",最大"23:59"  
  61.      * 如邮件反馈限制在每天8~17时(8:00~17:59),hourLimit设置格式为"8:00-17:59";  
  62.      * 如限制在12时(12:00~12:59),设置格式为"12:00-12:59".  
  63.      * 如果没有时间限制,设置格式为"-"  
  64.      * 如果起始日期大于终止日期,如"23:00-8:59",表示当日23:00到下一日8:59  
  65.      */  
  66.     private String hourLimit;   
  67.        
  68.     /** 触发任务创建时间 */  
  69.     private Timestamp createTime;   
  70.     /** 最后一次触发时间 */  
  71.     private Timestamp lastTime;   
  72.        
  73.        
  74.     public String getId()   
  75.     {   
  76.         return id;   
  77.     }   
  78.     public void setId(String id)   
  79.     {   
  80.         this.id = id;   
  81.     }   
  82.     public String getTaskDesc()   
  83.     {   
  84.         return taskDesc;   
  85.     }   
  86.     public void setTaskDesc(String taskDesc)   
  87.     {   
  88.         this.taskDesc = taskDesc;   
  89.     }   
  90.     public int getState()   
  91.     {   
  92.         return state;   
  93.     }   
  94.     public void setState(int state)   
  95.     {   
  96.         this.state = state;   
  97.     }   
  98.     public String getClazz()   
  99.     {   
  100.         return clazz;   
  101.     }   
  102.     public void setClazz(String clazz)   
  103.     {   
  104.         this.clazz = clazz;   
  105.     }   
  106.     public String getInParam()   
  107.     {   
  108.         return inParam;   
  109.     }   
  110.     public void setInParam(String inParam)   
  111.     {   
  112.         this.inParam = inParam;   
  113.     }   
  114.     public String getCycle()   
  115.     {   
  116.         return cycle;   
  117.     }   
  118.     public void setCycle(String cycle)   
  119.     {   
  120.         this.cycle = cycle;   
  121.     }   
  122.     public String getCycleLimit()   
  123.     {   
  124.         return cycleLimit;   
  125.     }   
  126.     public void setCycleLimit(String cycleLimit)   
  127.     {   
  128.         this.cycleLimit = cycleLimit;   
  129.     }   
  130.     public String getDayLimit()   
  131.     {   
  132.         return dayLimit;   
  133.     }   
  134.     public void setDayLimit(String dayLimit)   
  135.     {   
  136.         this.dayLimit = dayLimit;   
  137.     }   
  138.     public String getHourLimit()   
  139.     {   
  140.         return hourLimit;   
  141.     }   
  142.     public void setHourLimit(String hourLimit)   
  143.     {   
  144.         this.hourLimit = hourLimit;   
  145.     }   
  146.     public Timestamp getCreateTime()   
  147.     {   
  148.         return createTime;   
  149.     }   
  150.     public void setCreateTime(Timestamp createTime)   
  151.     {   
  152.         this.createTime = createTime;   
  153.     }   
  154.     public Timestamp getLastTime()   
  155.     {   
  156.         return lastTime;   
  157.     }   
  158.     public void setLastTime(Timestamp lastTime)   
  159.     {   
  160.         this.lastTime = lastTime;   
  161.     }   
  162.        
  163.   
  164.   
  165. }  
package cn.com.xinli.netb.entitys;

import java.io.Serializable;
import java.sql.Timestamp;

/**
 *  触发任务表
 * @author diaoyf
 *
 */
public class Trigger implements Serializable
{
	public static final long serialVersionUID = 1;
	
	/** id */
	private String id;
	
	/** 触发任务描述 */
	private String taskDesc;
	
	/** 触发状态 0:允许触发 1:取消触发 */
	private int state;
	
	/**
	 * 回调对象的包、类路径名
	 * 触发管理器根据此包、类路径名,通过反射机制实例化对象
	 */
	private String clazz;
	/** 回调方法输入参数 */
	private String inParam;

	/**
	 * 触发周期
	 * <li>atonce 表示一次(由小时触发器管理)</li>
	 * <li>min 表示每分</li>
	 * <li>hour 表示每小时</li>
	 * <li>day 表示每天</li>
	 * <li>month 表示每月</li>
	 * <li>3month 表示每季度</li>
	 * <li>year 表示每年</li>
	 */
	private String cycle;
	
	/**
	 *  触发时间限制
	 *  格式"2007/10/2 8:15:28-2007/10/3 18:15:30",表示任务存在时间
	 *  格式"-", 表示无触发时间限制
	 *  
	 */
	private String cycleLimit; 
	/**
	 * 触发日期限制
	 * 如月账单反馈限制在每月10~15日(包括15日),dayLimit设置格式为"10-15";
	 * 如限制在每月10日,设置格式为"10-10";
	 * 如果没有日期限制,设置格式为"-"
	 * 如果起始日期大于终止日期,如"25-10",表示当月25日到下月10日
	 */
	private String dayLimit; 
	/**
	 * 触发时间限制,时间规则最小"00:00",最大"23:59"
	 * 如邮件反馈限制在每天8~17时(8:00~17:59),hourLimit设置格式为"8:00-17:59";
	 * 如限制在12时(12:00~12:59),设置格式为"12:00-12:59".
	 * 如果没有时间限制,设置格式为"-"
	 * 如果起始日期大于终止日期,如"23:00-8:59",表示当日23:00到下一日8:59
	 */
	private String hourLimit;
	
	/** 触发任务创建时间 */
	private Timestamp createTime;
	/** 最后一次触发时间 */
	private Timestamp lastTime;
	
	
	public String getId()
	{
		return id;
	}
	public void setId(String id)
	{
		this.id = id;
	}
	public String getTaskDesc()
	{
		return taskDesc;
	}
	public void setTaskDesc(String taskDesc)
	{
		this.taskDesc = taskDesc;
	}
	public int getState()
	{
		return state;
	}
	public void setState(int state)
	{
		this.state = state;
	}
	public String getClazz()
	{
		return clazz;
	}
	public void setClazz(String clazz)
	{
		this.clazz = clazz;
	}
	public String getInParam()
	{
		return inParam;
	}
	public void setInParam(String inParam)
	{
		this.inParam = inParam;
	}
	public String getCycle()
	{
		return cycle;
	}
	public void setCycle(String cycle)
	{
		this.cycle = cycle;
	}
	public String getCycleLimit()
	{
		return cycleLimit;
	}
	public void setCycleLimit(String cycleLimit)
	{
		this.cycleLimit = cycleLimit;
	}
	public String getDayLimit()
	{
		return dayLimit;
	}
	public void setDayLimit(String dayLimit)
	{
		this.dayLimit = dayLimit;
	}
	public String getHourLimit()
	{
		return hourLimit;
	}
	public void setHourLimit(String hourLimit)
	{
		this.hourLimit = hourLimit;
	}
	public Timestamp getCreateTime()
	{
		return createTime;
	}
	public void setCreateTime(Timestamp createTime)
	{
		this.createTime = createTime;
	}
	public Timestamp getLastTime()
	{
		return lastTime;
	}
	public void setLastTime(Timestamp lastTime)
	{
		this.lastTime = lastTime;
	}
	


}

 

 

 

 

步骤2:建立 trigger ejb 的本地接口和远程接口,Bean实现

 

TriggerBean.java

 

Java代码 复制代码
  1. package cn.com.xinli.netb.ejb.trigger.service;   
  2.   
  3. import java.rmi.RemoteException;   
  4. import java.util.Date;   
  5.   
  6. import javax.ejb.SessionBean;   
  7.   
  8. import org.apache.log4j.Logger;   
  9.   
  10. import cn.com.xinli.netb.ejb.trigger.TriggerTask;   
  11.   
  12. public class TriggerBean implements SessionBean   
  13. {   
  14.     static Logger log = Logger.getLogger(TriggerBean.class);   
  15.        
  16.     private javax.ejb.SessionContext m_ctx = null;   
  17.   
  18.     /**  
  19.      * Sets the session context. Required by EJB spec.  
  20.      *   
  21.      * @param ctx  
  22.      *            A SessionContext object.  
  23.      */  
  24.     public void setSessionContext(javax.ejb.SessionContext ctx)    
  25.     {   
  26.         m_ctx = ctx;   
  27.     }   
  28.   
  29.     /**  
  30.      * Creates a bean. Required by EJB spec.  
  31.      *   
  32.      * @exception throws  
  33.      *                CreateException.  
  34.      */  
  35.     public void ejbCreate() throws javax.ejb.EJBException,   
  36.             javax.ejb.CreateException    
  37.     {   
  38.     }   
  39.   
  40.     /**  
  41.      * Removes the bean. Required by EJB spec.  
  42.      */  
  43.     public void ejbRemove()    
  44.     {   
  45.     }   
  46.   
  47.     /**  
  48.      * Loads the state of the bean from secondary storage. Required by EJB spec.  
  49.      */  
  50.     public void ejbActivate()    
  51.     {   
  52.     }   
  53.   
  54.     /**  
  55.      * Serializes the state of the bean to secondary storage. Required by EJB  
  56.      * spec.  
  57.      */  
  58.     public void ejbPassivate()    
  59.     {   
  60.     }   
  61.        
  62.     // ------------------------------------------   
  63.     // 业务方法   
  64.     // ------------------------------------------   
  65.     public String runTask(String triggerId, String clazz, String inParam) throws RemoteException   
  66.     {   
  67.         TriggerTask task = null;   
  68.         try  
  69.         {   
  70.             task = (TriggerTask)Class.forName(clazz).newInstance();   
  71.         }   
  72.         catch (Exception e)   
  73.         {   
  74.             log.error("反射调用触发任务类异常", e);   
  75.             throw new RemoteException("反射调用触发任务类异常");   
  76.         }   
  77.            
  78.         log.info("调用触发实现类,类名:" + clazz + ",参数:" + inParam + ",调用时间:" + new Date());   
  79.            
  80.         //回调任务类,并得到运行结果   
  81.         return task.doTask(triggerId, inParam);   
  82.     }   
  83. }  
package cn.com.xinli.netb.ejb.trigger.service;

import java.rmi.RemoteException;
import java.util.Date;

import javax.ejb.SessionBean;

import org.apache.log4j.Logger;

import cn.com.xinli.netb.ejb.trigger.TriggerTask;

public class TriggerBean implements SessionBean
{
	static Logger log = Logger.getLogger(TriggerBean.class);
	
	private javax.ejb.SessionContext m_ctx = null;

	/**
	 * Sets the session context. Required by EJB spec.
	 * 
	 * @param ctx
	 *            A SessionContext object.
	 */
	public void setSessionContext(javax.ejb.SessionContext ctx) 
	{
		m_ctx = ctx;
	}

	/**
	 * Creates a bean. Required by EJB spec.
	 * 
	 * @exception throws
	 *                CreateException.
	 */
	public void ejbCreate() throws javax.ejb.EJBException,
			javax.ejb.CreateException 
	{
	}

	/**
	 * Removes the bean. Required by EJB spec.
	 */
	public void ejbRemove() 
	{
	}

	/**
	 * Loads the state of the bean from secondary storage. Required by EJB spec.
	 */
	public void ejbActivate() 
	{
	}

	/**
	 * Serializes the state of the bean to secondary storage. Required by EJB
	 * spec.
	 */
	public void ejbPassivate() 
	{
	}
	
	// ------------------------------------------
	// 业务方法
	// ------------------------------------------
	public String runTask(String triggerId, String clazz, String inParam) throws RemoteException
	{
		TriggerTask task = null;
		try
		{
			task = (TriggerTask)Class.forName(clazz).newInstance();
		}
		catch (Exception e)
		{
			log.error("反射调用触发任务类异常", e);
			throw new RemoteException("反射调用触发任务类异常");
		}
		
		log.info("调用触发实现类,类名:" + clazz + ",参数:" + inParam + ",调用时间:" + new Date());
		
		//回调任务类,并得到运行结果
		return task.doTask(triggerId, inParam);
	}
}

 

 TriggerHome.java

 

Java代码 复制代码
  1. package cn.com.xinli.netb.ejb.trigger.service;   
  2.   
  3. import javax.ejb.EJBHome;   
  4.   
  5. public interface TriggerHome extends EJBHome   
  6. {   
  7.     TriggerRemote create() throws java.rmi.RemoteException, javax.ejb.CreateException;    
  8. }  
package cn.com.xinli.netb.ejb.trigger.service;

import javax.ejb.EJBHome;

public interface TriggerHome extends EJBHome
{
	TriggerRemote create() throws java.rmi.RemoteException, javax.ejb.CreateException; 
}

 

TriggerRemote.java 

 

Java代码 复制代码
  1. package cn.com.xinli.netb.ejb.trigger.service;   
  2.   
  3. import java.rmi.RemoteException;   
  4.   
  5. import javax.ejb.EJBObject;   
  6.   
  7. public interface TriggerRemote extends EJBObject   
  8. {   
  9.     /**  
  10.      * 调用反馈任务  
  11.      * @param triggerId 任务ID  
  12.      * @param clazz 反射类名  
  13.      * @param inParam 运行参数  
  14.      * @return  
  15.      *  <li>00: 成功,触发管理器将从触发表中取消此任务</li>  
  16.      *  <li>01: 失败,并触发管理器将从触发表中取消此任务</li>  
  17.      *  <li>10: 成功,触发管理器在触发表中保持此任务</li>  
  18.      *  <li>11: 失败,触发管理器在触发表中保持此任务</li>  
  19.      * @throws RemoteException  
  20.      */  
  21.     public String runTask(String triggerId, String clazz, String inParam) throws RemoteException;   
  22. }  
package cn.com.xinli.netb.ejb.trigger.service;

import java.rmi.RemoteException;

import javax.ejb.EJBObject;

public interface TriggerRemote extends EJBObject
{
	/**
	 * 调用反馈任务
	 * @param triggerId 任务ID
	 * @param clazz 反射类名
	 * @param inParam 运行参数
	 * @return
	 * 	<li>00: 成功,触发管理器将从触发表中取消此任务</li>
	 * 	<li>01: 失败,并触发管理器将从触发表中取消此任务</li>
	 * 	<li>10: 成功,触发管理器在触发表中保持此任务</li>
	 * 	<li>11: 失败,触发管理器在触发表中保持此任务</li>
	 * @throws RemoteException
	 */
	public String runTask(String triggerId, String clazz, String inParam) throws RemoteException;
}

 

 

步骤3:建立 TriggerManage ,用来操作 自动任务

Java代码
package cn.com.xinli.netb.ejb.trigger;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.Timestamp;

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

import cn.com.xinli.netb.ejb.common.HibernateUtil;
import cn.com.xinli.netb.entitys.Trigger;

/**
 * 触发任务管理
 * @author diaoyf
 *
 */
public class TriggerManage
{
	private static Logger log = Logger.getLogger(TriggerManage.class);
	

	
	/**
	 * 增加触发任务
	 * @param taskDesc 任务描述
	 * @param clazz 
	 * 		回调对象的包、类路径名。
	 * 		触发管理器根据此包、类路径名,通过反射机制实例化对象
	 * @param inParam
	 * 		回调方法输入参数
	 * @param cycle
	 * 		触发周期
	 * 	<li>atonce 表示一次(由小时触发器管理)</li>
	 * 	<li>min 表示每分</li>
	 * 	<li>hour 表示每小时</li>
	 * 	<li>day 表示每天</li>
	 * 	<li>week 表示每周</li>
	 * 	<li>month 表示每月</li>
	 * 	<li>3month 表示每季度</li>
	 * 	<li>year 表示每年</li>
	 * @param cycleLimit
	 * 		触发时间限制。
	 *  	<li>格式"2007/10/2 8:15:28-2007/10/3 18:15:30",表示任务存在时间;</li>
	 *  	<li>格式"-", 表示无触发时间限制。</li>
	 * @param dayLimit
	 * 		触发日期限制。
	 * 		<li>如月账单反馈限制在每月10~15日(包括15日),dayLimit设置格式为"10-15";</li>
	 * 		<li>如限制在每月10日,设置格式为"10-10";</li>
	 * 		<li>如果没有日期限制,设置格式为"-";</li>
	 * 		<li>如果起始日期大于终止日期,如"25-10",表示当月25日到下月10日。</li>
	 * 		<li>周触发任务: "w-1"表示周日发送、"w-2"表示周1发送、..."w-7"表示周6发送</li>
	 * @param hourLimit
	 * 		触发时间限制,时间规则最小"00:00",最大"23:59"。</li>
	 * 		<li>如邮件反馈限制在每天8~17时(8:00-17:59),hourLimit设置格式为"8:00-17:59";</li>
	 * 		<li>如限制在12时(12:00-12:59),设置格式为"12:00-12:59";</li>
	 * 		<li>如果没有时间限制,设置格式为"-";</li>
	 * 		<li>如果起始日期大于终止日期,如"23:00-8:59",表示当日23:00到下一日8:59。</li>
	 * @return 触发ID
	 * @throws Exception
	 */
	public static String addTask(
			String taskDesc,
			String clazz,
			String inParam,
			String cycle,
			String cycleLimit,
			String dayLimit,
			String hourLimit) throws Exception
	{
		Trigger trigger = new Trigger();
		trigger.setTaskDesc(taskDesc);
		trigger.setState(0);
		trigger.setClazz(clazz);
		trigger.setInParam(inParam);
		trigger.setCycle(cycle);
		trigger.setCycleLimit(cycleLimit);
		trigger.setHourLimit(hourLimit);
		trigger.setDayLimit(dayLimit);
		trigger.setCreateTime(new Timestamp(System.currentTimeMillis()));
		trigger.setLastTime(new Timestamp(0)); //默认1970年
		
		return addTask(trigger);
	}
	
	
	
	

	/**
	 * 增加触发任务
	 * @param trigger
	 * @throws Exception
	 */
	static String addTask(Trigger trigger) throws Exception
	{
		Session session = null;
		try 
		{
			session = HibernateUtil.getSession();
			
			//事物
//			Transaction tran = session.beginTransaction();

			session.save(trigger);
			session.flush();
			
//			tran.commit();
			
			return trigger.getId();
		} 
		catch (Exception e) 
		{
			log.error("获取Session异常", e);
			e.printStackTrace();
			throw new Exception("获取Session异常");
		} 
		finally
		{
			HibernateUtil.closeSession(session);
		}


	}
	

	
	/**
	 *  置触发任务为1(取消)
	 * @param trigger
	 */
	static void cancelTask(Trigger trigger)throws Exception
	{
		
		Session session = null;
		try
		{
			session = HibernateUtil.getSession();
			
			//修改状态标志, 1:取消
			trigger.setState(1);
			
			//事物
//			Transaction tran = session.beginTransaction();

			session.update(trigger);
			
//			tran.commit();
		}
		catch (Exception e)
		{
			log.error("置触发任务为1(取消)失败", e);
			throw new Exception("置触发任务为1(取消)失败");
		}
		finally
		{
			HibernateUtil.closeSession(session);
		}

	}
	
	/**
	 *  置触发任务为1(取消)
	 * @param trigger
	 */
	public static void cancelTask(String triggerId) throws Exception
	{
//		Session session = null;
		Connection conn = null;
		PreparedStatement prepStmt = null;
		try 
		{
//			session = HibernateUtil.currentSession();
			conn = HibernateUtil.getConnection();
			
//			conn.setAutoCommit(false);
			
			String sql = "UPDATE NETB_TRIGGER SET state = ? WHERE id = ?";
			prepStmt = conn.prepareStatement(sql);
			prepStmt.setInt(1, 1);
			prepStmt.setString(2, triggerId);
			
			prepStmt.execute();
			
//			conn.commit();
		} 
		catch (Exception e) 
		{
//			conn.rollback();
			log.error("置任务状态为1(取消)时,数据库操作异常", e);
			throw new Exception("置任务状态为1(取消)时,数据库操作异常");
		} 
		finally 
		{
			try
			{
				conn.close();
			}
			catch (Exception e)
			{
				
			}
		}
	}
	
	public static void updateTask(  String triggerId,
									String taskDesc,
									String clazz,
									String inParam,
									String cycle,
									String cycleLimit,
									String dayLimit,
									String hourLimit) throws Exception
	{
		Connection conn = null;
		PreparedStatement prepStmt = null;
		try 
		{
//			session = HibernateUtil.currentSession();
			conn = HibernateUtil.getConnection();
			
//			conn.setAutoCommit(false);
			
			String sql = "UPDATE NETB_TRIGGER SET taskDesc = ? ,clazz=?,inParam=?," +
					                            "cycle=?,cycleLimit=?,dayLimit=? and hourLimit=?"+
			                                    "WHERE id = ?";
			prepStmt = conn.prepareStatement(sql);
			prepStmt.setString(1, taskDesc);
			prepStmt.setString(2, clazz);
			prepStmt.setString(3, inParam);
			prepStmt.setString(4, cycle);
			prepStmt.setString(5, cycleLimit);
			prepStmt.setString(6, dayLimit);
			prepStmt.setString(7, hourLimit);
			prepStmt.setString(8, triggerId);
			prepStmt.execute();
			
//			conn.commit();
		} 
		catch (Exception e) 
		{
//			conn.rollback();
			log.error("置任务状态为1(取消)时,数据库操作异常", e);
			throw new Exception("置任务状态为1(取消)时,数据库操作异常");
		} 
		finally 
		{
			try
			{
				conn.close();
			}
			catch (Exception e)
			{
				
			}
		}
	}
	public static void main(String[] args) throws Exception
	{
		TriggerManage tm=new TriggerManage();
		Trigger trigger=new Trigger();
		trigger.setTaskDesc("测试2");
		System.out.println(tm.addTask(trigger));;
		
	}
}
 

步骤4:在ejb层建立 测试的业务方法,供自动任务调用

package cn.com.xinli.netb.ejb.trigger;
import org.apache.log4j.Logger;
import cn.com.xinli.netb.ejb.trigger.TriggerTask;

/**
 * 自动任务测试任务
 * 
 * @author huxl
 * 2008/9/23
 */
public class TriggerTaskTest implements TriggerTask 
{

    static Logger log = Logger.getLogger(TriggerTaskTest.class);
    public  String doTask(String triggerId, String inParam) 
    {
    	
    	log.info("自动任务测试任务开始执行");
    	log.info("triggerId:"+triggerId);
    	log.info("inParam:"+inParam);
    	return "10"; //成功继续保持此业务
    }
}
	

  

 

步骤5:自动任务框架,主要有两个线程,分钟线程 和小时线程 不停的去扫描数据库找到满足触发条件的任务,利用发射机制去执行,代码见附件。
如何使用这个自动任务框架
 
     1.讲ejb TriggerEJB 项目打成jar包放在jboss下
2.配置 TriggerThread 项目的 数据库配置文件
3.手工插入一条任务
 
 
4.启动 TriggerThread  中的Main ,观察我们插入的分钟任务的执行,看日志
TriggerThread 框架的日志:
0    [main] INFO  Main(34) - DB_URL:jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8
0    [main] INFO  Main(35) - DB_USER:root
16   [main] INFO  Main(36) - DB_PASSWD:12345678
16   [main] INFO  Main(37) - EJB_URL:jnp://127.0.0.1:1099
16   [Thread-0] INFO  TriggerHourThread(22) - 小时任务线程运行....
16   [Thread-1] INFO  TriggerMinThread(20) - 分钟任务线程运行....
609  [Thread-1] INFO  TriggerMinThread(38) - 运行触发任务
703  [Thread-1] INFO  TriggerMinThread(77) - sql:SELECT * FROM NETB_TRIGGER  WHERE 	state = ? AND 	cycle = ?  ORDER BY  	createTime
719  [Thread-1] INFO  TriggerMinThread(99) - 准备处理分钟任务:id=2003
719  [Thread-1] INFO  TriggerMinThread(130) - 开始处理分钟任务
719  [Thread-1] INFO  TriggerMinThread(149) - 上次触发时间:2009-08-01 18:00:32.0
750  [Thread-1] INFO  TriggerMinThread(150) - 当前时间:2009-08-01 18:15:04
750  [Thread-1] INFO  TriggerMinThread(157) - 分钟任务,id=2003距离上次触发已超过1分钟
781  [Thread-1] INFO  EJBHomeFactory(72) - EJB Home缓存中没有TriggerHome,创建之。
1094 [Thread-1] INFO  EJBHomeFactory(76) - 在JNDI中查询到了“Trigger”
1094 [Thread-1] INFO  EJBHomeFactory(79) - 成功获得远程Home对象,并存入缓存
1094 [Thread-1] INFO  Ejb(51) - 从Home工厂获取到了“TriggerHome”
1187 [Thread-1] INFO  Ejb(55) - 通过home成功获得remote对象
1203 [Thread-1] INFO  TriggerMinThread(162) - 分钟任务,id=2003返回值:10
 
jboss的日志
s_4_0_4_GA date=200605151000)] Started in 21s:578ms
18:15:05,062 INFO  [TriggerBean] 调用触发实现类,类名:cn.com.xinli.netb.ejb.trig
ger.TriggerTaskTest,参数:00,调用时间:Sat Aug 01 18:15:05 CST 2009
18:15:05,062 INFO  [TriggerTaskTest] 自动任务测试任务开始执行
18:15:05,062 INFO  [TriggerTaskTest] triggerId:2003
18:15:05,062 INFO  [TriggerTaskTest] inParam:00
 
OK!!
分享到:
评论

相关推荐

    级联H桥SVG无功补偿系统在不平衡电网中的三层控制策略:电压电流双闭环PI控制、相间与相内电压均衡管理,级联H桥SVG无功补偿系统在不平衡电网中的三层控制策略:电压电流双闭环PI控制、相间与相内电压均

    级联H桥SVG无功补偿系统在不平衡电网中的三层控制策略:电压电流双闭环PI控制、相间与相内电压均衡管理,级联H桥SVG无功补偿系统在不平衡电网中的三层控制策略:电压电流双闭环PI控制、相间与相内电压均衡管理,不平衡电网下的svg无功补偿,级联H桥svg无功补偿statcom,采用三层控制策略。 (1)第一层采用电压电流双闭环pi控制,电压电流正负序分离,电压外环通过产生基波正序有功电流三相所有H桥模块直流侧平均电压恒定,电流内环采用前馈解耦控制; (2)第二层相间电压均衡控制,注入零序电压,控制通过注入零序电压维持相间电压平衡; (3)第三层相内电压均衡控制,使其所有子模块吸收的有功功率与其损耗补,从而保证所有H桥子模块直流侧电压值等于给定值。 有参考资料。 639,核心关键词: 1. 不平衡电网下的SVG无功补偿 2. 级联H桥SVG无功补偿STATCOM 3. 三层控制策略 4. 电压电流双闭环PI控制 5. 电压电流正负序分离 6. 直流侧平均电压恒定 7. 前馈解耦控制 8. 相间电压均衡控制 9. 零序电压注入 10. 相内电压均衡控制 以上十个关键词用分号分隔的格式为:不

    GTX 1080 PCB图纸

    GTX 1080 PCB图纸,内含图纸查看软件

    深度优化与应用:提升DeepSeek润色指令的有效性和灵活性指南

    内容概要:本文档详细介绍了利用 DeepSeek 进行文本润色和问答交互时提高效果的方法和技巧,涵盖了从明确需求、提供适当上下文到尝试开放式问题以及多轮对话的十个要点。每一部分内容都提供了具体的示范案例,如指定回答格式、分步骤提问等具体实例,旨在指导用户更好地理解和运用 DeepSeek 提升工作效率和交流质量。同时文中还强调了根据不同应用场景调整提示词语气和风格的重要性和方法。 适用人群:适用于希望通过优化提问技巧以获得高质量反馈的企业员工、科研人员以及一般公众。 使用场景及目标:本文针对所有期望提高 DeepSeek 使用效率的人群,帮助他们在日常工作中快速获取精准的答案或信息,特别是在撰写报告、研究材料准备和技术咨询等方面。此外还鼓励用户通过不断尝试不同形式的问题表述来进行有效沟通。 其他说明:该文档不仅关注实际操作指引,同样重视用户思维模式转变——由简单索取答案向引导 AI 辅助创造性解决问题的方向发展。

    基于FPGA与W5500实现的TCP网络通信测试平台开发-Zynq扩展口Verilog编程实践,基于FPGA与W5500芯片的TCP网络通信测试及多路Socket实现基于zynq开发平台和Vivad

    基于FPGA与W5500实现的TCP网络通信测试平台开发——Zynq扩展口Verilog编程实践,基于FPGA与W5500芯片的TCP网络通信测试及多路Socket实现基于zynq开发平台和Vivado 2019软件的扩展开发,基于FPGA和W5500的TCP网络通信 测试平台 zynq扩展口开发 软件平台 vivado2019.2,纯Verilog可移植 测试环境 压力测试 cmd命令下ping电脑ip,同时采用上位机进行10ms发包回环测试,不丢包(内部数据回环,需要时间处理) 目前实现单socket功能,多路可支持 ,基于FPGA; W5500; TCP网络通信; Zynq扩展口开发; 纯Verilog可移植; 测试平台; 压力测试; 10ms发包回环测试; 单socket功能; 多路支持。,基于FPGA与W5500的Zynq扩展口TCP通信测试:可移植Verilog实现的高效网络通信

    Labview液压比例阀伺服阀试验台多功能程序:PLC通讯、液压动画模拟、手动控制与调试、传感器标定、报警及记录、自动实验、数据处理与查询存储,报表生成与打印一体化解决方案 ,Labview液压比例阀

    Labview液压比例阀伺服阀试验台多功能程序:PLC通讯、液压动画模拟、手动控制与调试、传感器标定、报警及记录、自动实验、数据处理与查询存储,报表生成与打印一体化解决方案。,Labview液压比例阀伺服阀试验台多功能程序:PLC通讯、液压动画模拟、手动控制与调试、传感器标定、报警管理及实验自动化,labview液压比例阀伺服阀试验台程序:功能包括,同PLC通讯程序,液压动画,手动控制及调试,传感器标定,报警设置及报警记录,自动实验,数据处理曲线处理,数据库存储及查询,报表自动生成及打印,扫码枪扫码及信号录入等~ ,核心关键词:PLC通讯; 液压动画; 手动控制及调试; 传感器标定; 报警设置及记录; 自动实验; 数据处理及曲线处理; 数据库存储及查询; 报表生成及打印; 扫码枪扫码。,Labview驱动的智能液压阀测试系统:多功能控制与数据处理

    华为、腾讯、万科员工职业发展体系建设与实践.pptx

    华为、腾讯、万科员工职业发展体系建设与实践.pptx

    基于遗传算法的柔性车间调度优化 附Matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    电网不对称故障下VSG峰值电流限制的柔性控制策略:实现电流平衡与功率容量的优化利用,电网不对称故障下VSG峰值电流限制的柔性控制策略:兼顾平衡电流与功率控制切换的动态管理,电网不对称故障下VSG峰值电

    电网不对称故障下VSG峰值电流限制的柔性控制策略:实现电流平衡与功率容量的优化利用,电网不对称故障下VSG峰值电流限制的柔性控制策略:兼顾平衡电流与功率控制切换的动态管理,电网不对称故障下VSG峰值电流限制的柔性不平衡控制(文章完全复现)。 提出一种在不平衡运行条件下具有峰值电流限制的可变不平衡电流控制方法,可灵活地满足不同操作需求,包括电流平衡、有功或无功恒定运行(即电流控制、有功控制或无功控制之间的相互切),注入电流保持在安全值内,以更好的利用VSG功率容量。 关键词:VSG、平衡电流控制、有功功率控制、无功功率控制。 ,VSG; 峰值电流限制; 柔性不平衡控制; 电流平衡控制; 有功功率控制; 无功功率控制。,VSG柔性控制:在电网不对称故障下的峰值电流限制与平衡管理

    libpinyin-tools-0.9.93-4.el7.x64-86.rpm.tar.gz

    1、文件内容:libpinyin-tools-0.9.93-4.el7.rpm以及相关依赖 2、文件形式:tar.gz压缩包 3、安装指令: #Step1、解压 tar -zxvf /mnt/data/output/libpinyin-tools-0.9.93-4.el7.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm 4、更多资源/技术支持:公众号禅静编程坊

    机器学习(预测模型):动漫《龙珠》相关的数据集

    数据集是一个以经典动漫《龙珠》为主题的多维度数据集,广泛应用于数据分析、机器学习和图像识别等领域。该数据集由多个来源整合而成,涵盖了角色信息、战斗力、剧情片段、台词以及角色图像等多个方面。数据集的核心内容包括: 角色信息:包含《龙珠》系列中的主要角色及其属性,如名称、种族、所属系列(如《龙珠》《龙珠Z》《龙珠超》等)、战斗力等级等。 图像数据:提供角色的图像资源,可用于图像分类和角色识别任务。这些图像来自动画剧集、漫画和相关衍生作品。 剧情与台词:部分数据集还包含角色在不同故事中的台词和剧情片段,可用于文本分析和自然语言处理任务。 战斗数据:记录角色在不同剧情中的战斗力变化和战斗历史,为研究角色成长和剧情发展提供支持。 数据集特点 多样性:数据集整合了角色、图像、文本等多种类型的数据,适用于多种研究场景。 深度:不仅包含角色的基本信息,还涵盖了角色的成长历程、技能描述和与其他角色的互动关系。 实用性:支持多种编程语言(如Python、R)的数据处理和分析,提供了详细的文档和示例代码。

    基于protues仿真的多功公交站播报系统设计(仿真图、源代码)

    基于protues仿真的多功公交站播报系统设计(仿真图、源代码) 该设计为基于protues仿真的多功公交站播报系统,实现温度显示、时间显示、和系统公交站播报功能; 具体功能如下: 1、系统使用51单片机为核心设计; 2、时钟芯片进行时间和日期显示; 3、温度传感器进行温度读取; 4、LCD12864液晶屏进行相关显示; 5、按键设置调节时间; 6、按键设置报站; 7、仿真图、源代码; 操作说明: 1、下行控制报站:首先按下(下行设置按键),(下行指示灯)亮,然后按下(手动播报)按键控制播报下一站; 2、上行控制报站:首先按上(上行设置按键),(上行指示灯)亮,然后按下(手动播报)按键控制播报下一站; 3、按下关闭播报按键,则关闭播报功能和清除显示

    基于微信小程序的琴房管理系统的设计与实现.zip

    采用Java后台技术和MySQL数据库,在前台界面为提升用户体验,使用Jquery、Ajax、CSS等技术进行布局。 系统包括两类用户:学生、管理员。 学生用户 学生用户只要实现了前台信息的查看,打开首页,查看网站介绍、琴房信息、在线留言、轮播图信息公告等,通过点击首页的菜单跳转到对应的功能页面菜单,包括网站首页、琴房信息、注册登录、个人中心、后台登录。 学生用户通过账户账号登录,登录后具有所有的操作权限,如果没有登录,不能在线预约。学生用户退出系统将注销个人的登录信息。 管理员通过后台的登录页面,选择管理员权限后进行登录,管理员的权限包括轮播公告管理、老师学生信息管理和信息审核管理,管理员管理后点击退出,注销登录信息。 管理员用户具有在线交流的管理,琴房信息管理、琴房预约管理。 在线交流是对前台用户留言内容进行管理,删除留言信息,查看留言信息。

    界面GUI设计MATLAB教室人数统计.zip

    MATLAB可以用于开发人脸识别考勤系统。下面是一个简单的示例流程: 1. 数据采集:首先收集员工的人脸图像作为训练数据集。可以要求员工提供多张照片以获得更好的训练效果。 2. 图像预处理:使用MATLAB的图像处理工具对采集到的人脸图像进行预处理,例如灰度化、裁剪、缩放等操作。 3. 特征提取:利用MATLAB的人脸识别工具包,如Face Recognition Toolbox,对处理后的图像提取人脸特征,常用的方法包括主成分分析(PCA)和线性判别分析(LDA)等。 4. 训练模型:使用已提取的人脸特征数据集训练人脸识别模型,可以选择支持向量机(SVM)、卷积神经网络(CNN)等算法。 5. 考勤系统:在员工打卡时,将摄像头捕获的人脸图像输入到训练好的模型中进行识别,匹配员工信息并记录考勤数据。 6. 结果反馈:根据识别结果,可以自动生成考勤报表或者实时显示员工打卡情况。 以上只是一个简单的步骤,实际开发过程中需根据具体需求和系统规模进行定制和优化。MATLAB提供了丰富的图像处理和机器学习工具,是开发人脸识别考勤系统的一个很好选择。

    hjbvbnvhjhjg

    hjbvbnvhjhjg

    HCIP、软考相关学习PPT

    HCIP、软考相关学习PPT提供下载

    绿豆BOX UI8版:反编译版六个全新UI+最新后台直播管理源码

    绿豆BOX UI8版:反编译版六个全新UI+最新后台直播管理源码 最新绿豆BOX反编译版六个UI全新绿豆盒子UI8版本 最新后台支持直播管理 作为UI6的升级版,UI8不仅修复了前一版本中存在的一些BUG,还提供了6套不同的UI界面供用户选择,该版本有以下特色功能: 在线管理TVBOX解析 在线自定义TVBOX 首页布局批量添加会员信息 并支持导出批量生成卡密 并支持导出直播列表管理功能

    vue3的一些语法以及知识点

    vue3的一些语法以及知识点

    西门子大型Fanuc机器人汽车焊装自动生产线程序经典解析:PLC博图编程与MES系统通讯实战指南,西门子PLC博图汽车焊装自动生产线FANUC机器人程序经典结构解析与MES系统通讯,西门子1500 大

    西门子大型Fanuc机器人汽车焊装自动生产线程序经典解析:PLC博图编程与MES系统通讯实战指南,西门子PLC博图汽车焊装自动生产线FANUC机器人程序经典结构解析与MES系统通讯,西门子1500 大型程序fanuc 机器人汽车焊装自动生产线程序 MES 系统通讯 大型程序fanuc机器人汽车焊装自动生产线程序程序经典结构清晰,SCL算法堆栈,梯形图和 SCL混编使用博图 V14以上版本打开 包括: 1、 PLC 博图程序 2 触摸屏程序 ,西门子1500; 大型程序; fanuc机器人; 汽车焊装自动生产线; MES系统通讯; SCL算法; 梯形图; SCL混编; 博图V14以上版本。,西门子博图大型程序:汽车焊装自动生产线MES系统通讯与机器人控制

    DeepSeek:从入门到精通

    DeepSeek:从入门到精通

    计及信息间隙决策与多能转换的综合能源系统优化调度模型:实现碳经济最大化与源荷不确定性考量,基于信息间隙决策与多能转换的综合能源系统优化调度模型:源荷不确定性下的高效碳经济调度策略,计及信息间隙决策及多

    计及信息间隙决策与多能转换的综合能源系统优化调度模型:实现碳经济最大化与源荷不确定性考量,基于信息间隙决策与多能转换的综合能源系统优化调度模型:源荷不确定性下的高效碳经济调度策略,计及信息间隙决策及多能转的综合能源系统优化调度 本代码构建了含风电、光伏、光热发电系统、燃气轮机、燃气锅炉、电锅炉、储气、储电、储碳、碳捕集装置的综合能源系统优化调度模型,并考虑P2G装置与碳捕集装置联合运行,从而实现碳经济的最大化,最重要的是本文引入了信息间隙决策理论考虑了源荷的不确定性(本代码的重点)与店铺的47代码形成鲜明的对比,注意擦亮眼睛,认准原创,该代码非常适合修改创新,,提供相关的模型资料 ,计及信息间隙决策; 综合能源系统; 优化调度; 多能转换; 碳经济最大化; 风电; 光伏; 燃气轮机; 储气; 储电; 储碳; 碳捕集装置; P2G装置联合运行; 模型资料,综合能源系统优化调度模型:基于信息间隙决策和多能转换的原创方案

Global site tag (gtag.js) - Google Analytics