通过添加注解@Transactional,Spring IOC容器就会自动为执行的方法添加数据库事物,这种添加的事物的实现原理也很容易被猜测到,通过把事物(数据库连接)信息存储到线程局部变量中,在方法体的前后执行开启连接,提交或回滚事物即可,这也是通过切面的方式添加上去的。
通过源码阅读,探索怎样手动添加事物,demo代码如下:
......
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
......
@Configuration
@EnableAsync
@EnableScheduling
public class HttpRetryTask {
private final static Logger logger = LoggerFactory.getLogger(HttpRetryTask.class);
private RestTemplate restTemplate = new RestTemplate();
@Autowired
private PlatformTransactionManager txManager;
@Autowired
private HttpMessageMapper httpMessageMapper;
@Scheduled(initialDelay = 60 * 1000, fixedDelay = 10 * 60 * 1000)
public void retryHttpRequest() {
//检索状态是retry的http任务
List<HttpMessage> request = httpMessageMapper.getMessagesByState(HttpMessage.State.RETRY.name());
//execute request without retry flag
for (int i = 0; i < request.size(); i++) {
//使用自定义事物,防止事物conn独占时间过长。
TransactionStatus transaction = txManager.getTransaction(new DefaultTransactionDefinition());//开启事物,可以理解为就是从dataSource里获取一个connection对象
try {
processRequest(request.get(i));
} catch (Exception e) {
txManager.rollback(transaction);//回滚事物
continue;
}
txManager.commit(transaction);//提交事物
}
}
}
源码参考:
org.springframework.transaction.interceptor.TransactionAspectSupport的方法invokeWithinTransaction