Spring 메모 트랜잭션이 작동하지 않는 솔루션
7988 단어 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 record
template.update(UPDATE_RECORD, record);
//2 update cell
template.update(UPDATE_CELLS, record);
//3 update full_search
record.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 UPDATECELLS 안의 문장을 고의로 잘못 쓴 다음에 시작할 때 실행한 결과 역시 첫 번째 업데이트 문장이 성공했고 뒤의 문장은 성공하지 못했으며 굴러가지 않았다.
이 클래스의 상위 클래스는 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;
}
//constents
private 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"
class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="dataSource" 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-class="true"/>
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSourceProxy"/>
</bean>
<bean id="dataSourceProxy" class="com.tongcard.osf.datasource.DynamicDataSource">
<property name="targetDataSources">
<ref local="dataSourceMap" />
</property>
<property name="defaultTargetDataSource" ref="db1"/>
</bean>
오늘 하루 종일 어디의 문제인지, 어느 신이 문제가 어디에 있는지 알아내셨는지 많이 가르쳐 주셔서 대단히 감사합니다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Spring 메모 트랜잭션이 작동하지 않는 솔루션현재 한 프로젝트를 인수하여 한 무더기의 버그를 해결해야 한다. 그 중 하나는 같은 방법에서 두 장의 시계status의 값을 수정하는 것이다. 한 장의 시계는 수정되었고 다른 한 장의 시계는 변하지 않았다. 코드에 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.