spring事务回滚处理:
准备:配置好spring+mybatis环境。
一、XML方式配置spring事务处理
第一步: spring.xml配置:
第二步:编写测试代码:
TestController.java
package org.jun.controller;
import org.jun.controller.base.AbstractController;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping("test")
public class TestController extends AbstractController {
@ResponseBody
@RequestMapping("trade")
public String trade(){
try {
testService.trade();
} catch (Exception e) {
logger.error("[error] trade error!" + e);
}
return "success";
}
}
==============================================================================
TestService.java
package org.jun.service;
public interface TestService {
void trade() throws Exception;
}
==========================================================================
TestServiceImpl.java
package org.jun.service;
import javax.annotation.Resource;
import org.jun.mapper.TestMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@Service
public class TestServiceImpl implements TestService {
@Resource
private TestMapper testMapper;
public void trade() throws Exception{
try {
testMapper.updateBalance();
int i = 10/0;
testMapper.record();
} catch (RuntimeException e) {
throw new Exception(e);
}
}
}
第三步:结果分析:
如果事务正常回滚,表中数据无变化。
如果事务没有回滚,表中对应记录的余额被更新,但没有新添加的记录

第四步:如果事务无法回滚:
检查:确认有抛异常,确认扫描包的位置正确,确认没有重复扫描对应包。
通常只会在service层处理事务回滚操作.
一、注解方式配置spring事务处理
XML配置:
spring.xml:
springmvc.xml:
TestController.java:
package org.web.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.web.controller.base.AbstractController;
import org.web.domain.User;
@Controller
@RequestMapping("test")
public class TestController extends AbstractController{
@ResponseBody
@RequestMapping("trade")
public String trade() {
try {
User u = new User();
u.setId(1);
u.setUsername("xiejunbo");
u.setPwd("123456");
testService.trade(u);
} catch (Exception e) {
logger.error("[error]" + e);
}
return "success";
}
}
TestServiceImpl.java:
package org.web.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.web.domain.User;
import org.web.mapper.TestMapper;
import org.web.service.TestService;
@Service
public class TestServiceImpl implements TestService {
@Autowired
private TestMapper testMapper;
@Transactional(rollbackFor=Exception.class)
public void trade(User u) throws Exception {
try {
testMapper.substract(u);
u.setId(2);
testMapper.add(u);
testMapper.record(u);
int i = 10/0;
} catch (Exception e) {
throw new Exception(e);
}
}
}
注意:扫描包时,对事务注解annotation只扫描一次,重复扫描会导致事务失效。
操作结果:
多线程异步处理:
public ThreadPool(int poolSize, String poolName) {
super(poolSize, poolSize, 0L, TimeUnit.SECONDS, new LinkedBlockingQueue(), new NamingThreadFactory(
poolName));
this.poolName = poolName;
}
public String getPoolName() {
return poolName;
}
public void setPoolName(String poolName) {
this.poolName = poolName;
}
private static class NamingThreadFactory implements ThreadFactory {
private String threadName;
private AtomicInteger counter = new AtomicInteger(1);
public NamingThreadFactory(String threadName) {
this.threadName = threadName;
}
@Override
public Thread newThread(Runnable r) {
int index = counter.getAndIncrement();
return new Thread(r, threadName + "-" + index);
}
}
public String toString() {
String str = super.toString();
int idx = str.indexOf("[");
if (idx == -1) {
return "[name = " + poolName + "]";
}
String s = str.substring(idx + 1);
return "[name = " + poolName + ", " + s;
}
}