读书人

Spring注脚事务没有起作用解决方案

发布时间: 2012-12-20 09:53:21 作者: rapoo

Spring注解事务没有起作用解决方案

如今接手一个项目,要解决一堆bug,其中有一个问题是,在同一个方法中修改两张表status的值 ,一张表修改了,另一张表没变,看代码里写了Spring注解事务,看样子是没有起到作用。

代码

/** * @author : cg * date :2010-3-15 * description :时段结束时调度 */public class YdRecord extends AbstractMerchantTimerTask {/** * 预订订单状态变更 */@Override@Transactional(readOnly = false, propagation = Propagation.REQUIRED)public void run(String merchantId, String merchantName, DataSource ds) {if(log.isDebugEnabled()) log.debug("开始跑YdRecord.." + merchantName);NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(ds);HashMap<String, Object> parMap = new HashMap<String, Object>();parMap.put(MERCHANT_ID, merchantId);List<Map<String,Object>> records = template.queryForList(GET_RECORD_SQL, parMap);if(records != null && records.size() != 0){for(int i=0;i<records.size();i++){Map<String,Object> record = records.get(i);String status = (String) record.get(STATUS);//若订单状态为 'normal' ,则置为'cancel';若订单状态为'arrivaled',则置为'over'if("normal".equals(status))record.put(STATUS, "cancel");if("arrivaled".equals(status))record.put(STATUS, "over");//1 update recordtemplate.update(UPDATE_RECORD, record);//2 update celltemplate.update(UPDATE_CELLS, record);//3 update full_searchrecord.put("OLDSTR", "normal".equals(status)?"未到达":"已到达");record.put("NEWSTR", "normal".equals(status)?"取消":"已完成");template.update(UPDATE_FULL_SEARCH, record);if(log.isDebugEnabled()) log.debug("结束YdRecord.." + merchantName);}}}private static final String MERCHANT_ID = "MERCHANT_ID";private static final String STATUS = "STATUS";private final static String GET_RECORD_SQL = "" +"select t.record_id, " +"       t.status " +" from yd_record t " +" where t.merchant_id = :MERCHANT_ID " +"   and ( t.status = 'normal' or t.status = 'arrivaled' )  " +" and (select to_date(substr(t.pre_arrival_time,0,10)||a.end_time, 'yyyy-MM-DD hh24:mi:ss') "+        "  from yd_periods a "+        " where a.store_id = t.store_id "+        "   and a.periods_id = t.pre_period) <= to_date(to_char(sysdate+1, 'yyyy-MM-DD hh24:mi:ss'), 'yyyy-MM-DD hh24:mi:ss')";private final static String UPDATE_RECORD      = "update yd_record t set t.update_time = sysdate,t.status = :STATUS where t.record_id = :RECORD_ID";private final static String UPDATE_CELLS       = "update yd_cell_record t set t.status = :STATUS where and t.record_id = :RECORD_ID";private final static String UPDATE_FULL_SEARCH = "update yd_full_search t set t.info = replace(t.info,:OLDSTR,:NEWSTR) where t.record_id = :RECORD_ID";}

?

我将String UPDATE_CELLS?????? 里面的语句故意写错,然后启动定时,执行后发现果然是第一个update语句成功了,后面的一句没成功, 没有回滚。

?

这个类的父类是AbstractMerchantTimerTask

import java.util.Date;import javax.sql.DataSource;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.springframework.transaction.annotation.Propagation;import org.springframework.transaction.annotation.Transactional;import com.tongcard.platform.tip.sp.timer.SingleMerchantTimerTask;import com.tongcard.platform.tip.sp.timer.TimerLogUtil;import com.tongcard.platform.tip.timer.TimerException;import com.tongcard.platform.tip.timer.model.TimerDefinition;import com.tongcard.osf.datasource.DataSourceUtil;public abstract class AbstractMerchantTimerTask implements SingleMerchantTimerTask, IMerchantTimerTask {protected static Log log = LogFactory.getLog(AbstractMerchantTimerTask.class);public void runWithLog(String timerId,String timerName, String merchantId,String merchantName,String dataSourceName, DataSource ds, TimerLogUtil timerLogUtil ){DataSourceUtil.setCurrentDataSourceName(dataSourceName);long startTime = System.currentTimeMillis();String result = SUCCESS;String errorInfo = null;try{this.merchantTaskDelegate.delegate(this,merchantId, merchantName,ds);//从这里调用的方法,该类中定义父级注解。}catch(Throwable e){errorInfo = e.getMessage();log.error(e.getMessage(),e);result = FAILED;throw new TimerException(errorInfo,e);}finally{long endTime = System.currentTimeMillis();timerLogUtil.log(merchantId, merchantName, timerId, timerName, new Date(startTime), new Date(endTime), (endTime-startTime)/1000, result, errorInfo);}}public String getDefaultTimerId() {return this.getClass().getName();}public String getDefaultTimerName() {return this.getClass().getName();}/* (non-Javadoc) * @see com.tongcard.platform.tip.sp.timer.task.IMerchantTimerTask#run(java.lang.String, java.lang.String, javax.sql.DataSource) */abstract public void run(String merchantId,String merchantName,DataSource ds);private IMerchantTimerTaskTransDelegate merchantTaskDelegate = null;public IMerchantTimerTaskTransDelegate getMerchantTaskDelegate() {return merchantTaskDelegate;}public void setMerchantTaskDelegate(IMerchantTimerTaskTransDelegate merchantTaskDelegate) {this.merchantTaskDelegate = merchantTaskDelegate;}//constentsprivate static final String SUCCESS = "success";private static final String FAILED = "failed";

?

?

?

?

?写有注解的部分的接口IMerchantTimerTaskTransDelegate 中定义:

public interface IMerchantTimerTaskTransDelegate {@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)public void delegate(IMerchantTimerTask mtt, String merchantId,String merchantName,DataSource ds);}

?

?

配置文件 :

<bean id="sqlMapClient"ref="dataSourceProxy" /><property name="configLocation"><value>classpath:/timerconfig/ibatis/sqlmap-config.xml</value></property><property name="lobHandler" ref="lobHandler"/></bean><!-- 支持  @Transactional 标记 --><tx:annotation-driven transaction-manager="txManager" proxy-target-ref="dataSourceProxy"/>  </bean><bean id="dataSourceProxy" />         </property>          <property name="defaultTargetDataSource" ref="db1"/>       </bean> 

?今天一整天都在找是哪里的问题,哪位大神看出问题在哪里,还请多多指教,万分感激。

读书人网 >编程

热点推荐