工程调用流程:服务生产者=>Service层=>Dao层。java
在“消费层”只进行“单一”服务调用时,可暂时不用考虑“分布式”事务问题。此情形下事务仍是使用Spring注解事务,只要考虑事务是配置在“服务生产者”仍是“Service层”。git
0)controller层:UserControllergithub
@RequestMapping("addUser") @ResponseBody public Boolean addUser(String name,@DateTimeFormat(pattern = "yyyy-MM-dd") Date birthday) throws Exception{ if(StringUtils.isEmpty(name)) throw new DemoException("前置参数name为空"); return userApi.add(name,birthday); }
1)dubbo接口:UserApi.java数据库
Boolean add(String name,Date birthday) throws Exception;
2)dubbo接口实现-服务生产者:UserApiImpl.javaapp
//@Transactional(rollbackFor = Exception.class) @Override public Boolean add(String name, Date birthday) throws Exception { try { User user = new User(); user.setName(name); user.setBirthday(birthday); return userService.add(user); }catch (DemoException e){ LOGGER.error("添加用户异常",e); throw new Exception("添加用户异常",e); } }
3)Service层:UserService.java分布式
@Transactional(rollbackFor = DemoException.class) public Boolean add(User user) throws DemoException{ int count = userDao.add(user); if(count != 1){ throw new DemoException("数据库更新不为1"); } LOGGER.info("新增user主键id=>{}",user.getId()); if(1 == 1) { throw new DemoException("测试事务事务是否回滚"); } return true; }
说明:注解事务中回滚默认是RuntimeException,DemoException并不是RuntimeException,因此须要在rollbackFor 。ide
4)测试结果测试
http://localhost:8086/demo-consumer/user/addUser.do?name=wsy&birthday=2011-11-11spa
页面显示以下:code
数据库表无对应记录
即事务配置生效,数据回滚。
把UserApiImpl.java中注解事务放开,注释UserService中事务配置。
测试结果:即事务配置生效,数据回滚。
补充说明:在有些dubbo版本中,若是事务配置在服务生产者,会有各类问题出现。
工程中dubbo版本是从https://github.com/dangdangdotcom/dubbox下载源码从新编译,已没此问题。