读书人

集群环境上的单例任务调度基类

发布时间: 2012-09-10 11:02:33 作者: rapoo

集群环境下的单例任务调度基类

最近为公司框架提供了基于ID的单例的任务调度基类,用于集群的环境下,一个任务同一时间只能被调度一次。

?

接口声明
继承该基类的任务需要覆盖两个抽象函数:
??????? protected abstract String getServiceID();//服务ID,与数据库中的和timeservice.xml中的要配置相同???????
??????? protected abstract void doTask();//执行任务,需覆盖的业务方法

?

实现机理

每个任务要有唯一的ServiceId,该任务在t_s_sys_timeservice 中有一条记录,同时有一个state记录着状态信息,state为0表示未占用,state为1表示已占用。

设计上还要考虑处理异常的情况,通过引入一个超时时间,如果已经超时,则认为改状态为未被占用

?

关键代码

?

public abstract class SingletonTimeService extends TimeService {private String selectSql = "select * from t_s_sys_timeservice where (id = ? and state = 0) or (id = ? and sysdate > update_date + timeout_interval/86400 ) for update"; private String updateLockSql = "update t_s_sys_timeservice set update_date = sysdate,state = 1 where id = ?"; private String updateUnlockSql = "update t_s_sys_timeservice set update_date = sysdate,state = 0 where id = ?"; public void doTimeService() {ThreadContext ctx = ThreadContext.getThreadContext();FrameworkTransaction _tr = null;Connection _conn = null;try {_conn = DataSourceFactory.getDefaultConnection();_tr = new JDBCTransaction(_conn);_tr.begin();//争任务,此处无法采用框架提供的封装PreparedStatement ps = null;ResultSet rs = null;try {ps = _conn.prepareStatement(selectSql);ps.setString(1, getServiceID());ps.setString(2, getServiceID());rs = ps.executeQuery();} catch (SQLException ex) {throw ex;}if(rs.next()){//抢到任务SingleDBHelper helper = new SingleDBHelper(_conn);//锁定任务try{helper.executeUpdate(updateLockSql,ParamsMaker.makeParams(getServiceID()));}catch(Exception e){e.printStackTrace();}//执行任务try{doTask();}catch(Throwable e){e.printStackTrace();}//解锁try{helper.executeUpdate(updateUnlockSql,ParamsMaker.makeParams(getServiceID()));}catch(Exception e){e.printStackTrace();}}//事务相关操作_tr.commit();} catch (Exception ex) {if (_tr != null) {try {_tr.rollback();} catch (Exception ex1) {}}throw new ServiceInvokeException("调度异常", ex);} finally {ctx.runShieldStatements();DataSourceFactory.release(_conn);}}protected abstract String getServiceID();protected abstract void doTask();}

?

读书人网 >编程

热点推荐