上个月在搞毕业设计的时候,需要对在程序中对更新、插入语句进行事务管理,当用户输入不合理或者出现某种异常的时候及时的回滚事务,保证数据的正确性。在网上查找相关资料得知大多数时候用的是@Transactional这个注解,关于这个注解的使用方法和自己遇到的问题我整理为以下几点:
第一步:除了Spring MVC的ApplicationContext的常规配置(诸如dataSource之类),需要配置一个事务管理的bean
<!-- (事务管理)transaction manager, use JtaTransactionManager for global tx -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
第二步:在Spring MVC整合的配置文件中添加开启使用注解的属性:
<!--开启@Transactional注解-->
<tx:annotation-driven proxy-target-class="true" transaction-manager="transactionManager"/>
当然还得引用响应的命名空间以及地址。
第三步:在Service层涉及事物的方法上使用@Transactional注解
因为我Service层比较简单,所以我直接在Controller层的方法上使用,也能生效;
@RequestMapping("/RegisterUser")
@Transactional(propagation = Propagation.REQUIRED)
public @ResponseBody
HashMap doRegister(HttpServletRequest request, HttpServletResponse response, @RequestBody User user)
并可以设置propagation等属性。
使用的时候遇到的问题:
一、Spring容器中的@Transactional注解默认只会去捕捉RuntimeException,其他的异常不会回滚,可以在注解属性设置自定义回滚的异常。
二、在方法中有自定义的try catch块的时候,有可能不生效,这时候需要自己手动的去抛出异常,如下:
/*
purpose: 用户在管理员未审核之前撤回自己的申请记录
author: linsong.wei
when: 2017-11-15 19:07:38
*/
@RequestMapping(value = "/recallApply", method = RequestMethod.GET)
@Transactional(propagation = Propagation.REQUIRED)
public @ResponseBody
HashMap doRecallApply(HttpServletRequest request, HttpServletResponse response) {
HashMap map = new HashMap();
int laId = Integer.parseInt(request.getParameter("laId"));
LendingApply lendingApply = lendingApplyService.selectByPrimaryKey(laId);
int flag = -1;
try {
//删除申请表里的本记录 且 user_id = 当前用户
lendingApplyService.deleteByPkAndUser(lendingApply);
//同时删除历史表的lhlaid=laid and lh_user_id=当前用户的纪录
LendingHistory lendingHistory = lendingHistoryService.selectByLaId(laId);//找到对应的历史纪录
lendingHistoryService.deleteByPkAndUser(lendingHistory);
//删除费用记录表里的记录
expenseService.deleteByLaId(laId);
flag = 1;
} catch (Exception e) {
flag = -1;
throw new RuntimeException();
}
在看别人的项目和学习慕课网的课程中,有的人在使用该注解的时候在方法头会显示声明并抛出异常,但在我项目中似乎不需要那么做,也能正常回滚?
原因还有待研究。。。