今天尝试事务回滚的时候遇到一个问题:
我在controller中try一个方法,该方法执行一条插入语句,带有@Transactional注解,并会抛出一个异常。controller中catch这个异常之后,从控制台输出插入的内容。
我感觉应该是插入语句回滚,内容被删除,然而结果是:数据库确实回滚了,也确实输出了被插入的内容。
想问问大神,这是什么原理?
controller:
@RequestMapping("/regist")
public ModelAndView regist(HttpServletRequest request, User user) throws Exception {
if (checkParams(new String[] { user.getUsername(), user.getPassword() })) {
//TODO @Transaction check if the account has already exist
try {
userService.saveUser(user);
} catch (Exception e) {
// TODO Auto-generated catch block
System.out.println("regist"+e.getMessage());
request.setAttribute("describe", e.getMessage());
}
request.setAttribute("username", user.getUsername());
request.setAttribute("password", user.getPassword());
System.out.println(user);
return new ModelAndView("succ");
}
return new ModelAndView("regist");
}
service:
@Transactional(rollbackFor = Exception.class)
public void saveUser(User user) throws Exception {
if (user != null && user.getId() != null) {
userDao.updateUser(user);
} else {
// TODO find if there is a repetition, can also use SQL
try {
List<User> allUser = userDao.getUser();
userDao.insertUser(user);
for (User _user : allUser) {
if (_user.getUsername().equals(user.getUsername()))
throw new Exception("The account is exist!");
}
} catch (Exception e) {
throw e;
}
}
}
控制台输出结果:
User [userid=1, username=1, password=1]
registThe account is exist!
User [userid=2, username=1, password=2]
数据库:
我在controller中try一个方法,该方法执行一条插入语句,带有@Transactional注解,并会抛出一个异常。controller中catch这个异常之后,从控制台输出插入的内容。
我感觉应该是插入语句回滚,内容被删除,然而结果是:数据库确实回滚了,也确实输出了被插入的内容。
想问问大神,这是什么原理?
controller:
@RequestMapping("/regist")
public ModelAndView regist(HttpServletRequest request, User user) throws Exception {
if (checkParams(new String[] { user.getUsername(), user.getPassword() })) {
//TODO @Transaction check if the account has already exist
try {
userService.saveUser(user);
} catch (Exception e) {
// TODO Auto-generated catch block
System.out.println("regist"+e.getMessage());
request.setAttribute("describe", e.getMessage());
}
request.setAttribute("username", user.getUsername());
request.setAttribute("password", user.getPassword());
System.out.println(user);
return new ModelAndView("succ");
}
return new ModelAndView("regist");
}
service:
@Transactional(rollbackFor = Exception.class)
public void saveUser(User user) throws Exception {
if (user != null && user.getId() != null) {
userDao.updateUser(user);
} else {
// TODO find if there is a repetition, can also use SQL
try {
List<User> allUser = userDao.getUser();
userDao.insertUser(user);
for (User _user : allUser) {
if (_user.getUsername().equals(user.getUsername()))
throw new Exception("The account is exist!");
}
} catch (Exception e) {
throw e;
}
}
}
控制台输出结果:
User [userid=1, username=1, password=1]
registThe account is exist!
User [userid=2, username=1, password=2]
数据库:
我没明白!!! 首先,你说要出错,是出错,你自己抛异常的,然后你那个insert不是回滚了么?数据库不是本身就有一条数据?怎么会将原先的删除呢?只是本次事务控制中出现的所有事务操作保持一致.但是事务控制不能删除之前的数据呀,不然数据库要怎么存数据?
我没明白!!! 首先,你说要出错,是出错,你自己抛异常的,然后你那个insert不是回滚了么?数据库不是本身就有一条数据?怎么会将原先的删除呢?只是本次事务控制中出现的所有事务操作保持一致.但是事务控制不能删除之前的数据呀,不然数据库要怎么存数据?如果你说原先你的数据库没有数据,那你这个抛异常的if条件不满足,异常都没有抛出来,事务不会回滚
我没明白!!! 首先,你说要出错,是出错,你自己抛异常的,然后你那个insert不是回滚了么?数据库不是本身就有一条数据?怎么会将原先的删除呢?只是本次事务控制中出现的所有事务操作保持一致.但是事务控制不能删除之前的数据呀,不然数据库要怎么存数据?如果你说原先你的数据库没有数据,那你这个抛异常的if条件不满足,异常都没有抛出来,事务不会回滚应该说 抛出的异常不是exception,应为异常不是你throw的,是那个_user.getxxx报错的
可以选择去掉try...catch@Transactional(rollbackFor = Exception.class)
public void saveUser(User user) throws Exception {
if (user != null && user.getId() != null) {
userDao.updateUser(user);
} else {
// TODO find if there is a repetition, can also use SQL
List<User> allUser = userDao.getUser();
userDao.insertUser(user);
for (User _user : allUser) {
if (_user.getUsername().equals(user.getUsername()))
throw new Exception("The account is exist!");
}
}
}或者在catch加上TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();@Transactional(rollbackFor = Exception.class)
public void saveUser(User user) throws Exception {
if (user != null && user.getId() != null) {
userDao.updateUser(user);
} else {
// TODO find if there is a repetition, can also use SQL
try {
List<User> allUser = userDao.getUser();
userDao.insertUser(user);
for (User _user : allUser) {
if (_user.getUsername().equals(user.getUsername()))
throw new Exception("The account is exist!");
}
} catch (Exception e) {
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
throw e;
}
}
}
不好意思 眼瞎 看代码的时候没有仔细看到你声明了Exception回滚