@Service("userService")
public class UserServiceImpl implements UserService {
@Resource
UserMapper userMapper;
@Autowired
RedisUtil redisUtil;
@Override
public List<User> getAllUsers() {
List<User> users = userMapper.getAllUsers();
return users;
}
@Override
@Transactional
public void updateUserAge() {
userMapper.updateUserAge(1);
int i= 1/0;
userMapper.updateUserAge(2);
}
}
数据库操作:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.aphysia.springdocker.mapper.UserMapper">
<select id="getAllUsers" resultType="com.aphysia.springdocker.model.User">
SELECT * FROM user
</select>
<update id="updateUserAge" parameterType="java.lang.Integer">
update user set age=age+1 where id =#{id}
</update>
</mapper>
先获取http://localhost:8081/getUserList所有的用户看看:
在调用更新接口,页面抛出错误了:
控制台也出现了异常,意思是除以0,异常:
java.lang.ArithmeticException: / by zero
at com.aphysia.springdocker.service.impl.UserServiceImpl.updateUserAge(UserServiceImpl.java:35) ~[classes/:na]
at com.aphysia.springdocker.service.impl.UserServiceImpl$$FastClassBySpringCGLIB$$c8cc4526.invoke(<generated>) ~[classes/:na]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.3.12.jar:5.3.12]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:783) ~[spring-aop-5.3.12.jar:5.3.12]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.3.12.jar:5.3.12]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753) ~[spring-aop-5.3.12.jar:5.3.12]
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123) ~[spring-tx-5.3.12.jar:5.3.12]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388) ~[spring-tx-5.3.12.jar:5.3.12]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-5.3.12.jar:5.3.12]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.12.jar:5.3.12]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753) ~[spring-aop-5.3.12.jar:5.3.12]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:698) ~[spring-aop-5.3.12.jar:5.3.12]
at com.aphysia.springdocker.service.impl.UserServiceImpl$$EnhancerBySpringCGLIB$$25070cf0.updateUserAge(<generated>) ~[classes/:na]
结论:必须设置为InnoDB引擎,事务才生效。 2. 方法不能是 private
事务必须是public方法,如果用在了private方法上,那么事务会自动失效,但是在IDEA中,只要我们写了就会报错:Methods annotated with '@Transactional' must be overrideable,意思是事务的注解加上的方法,必须是可以重写的,private方法是不可以重写的,所以报错了。
public void testTransaction(){
updateUserAge();
}
@Transactional
public void updateUserAge(){
userMapper.updateUserAge(1);
int i = 1/0;
userMapper.updateUserAge(2);
}
在controller里面调用的是没有事务注解的方法,再间接调用事务方法:
@RequestMapping("/update")
@ResponseBody
public int update() throws Exception{
userService.testTransaction();
return 1;
}
@Transactional
public void updateUserAge() {
new Thread(
new Runnable() {
@Override
public void run() {
userMapper.updateUserAge(1);
}
}
).start();
int i = 1 / 0;
userMapper.updateUserAge(2);
}
@Service("userService")
public class UserServiceImpl {
@Autowired
UserServiceImpl2 userServiceImpl2;
@Resource
UserMapper userMapper;
@Transactional
public void updateUserAge() {
try {
userMapper.updateUserAge(1);
userServiceImpl2.updateUserAge();
}catch (Exception ex){
ex.printStackTrace();
}
}
}
调用的另外一个事务:
@Service("userService2")
public class UserServiceImpl2 {
@Resource
UserMapper userMapper;
@Transactional
public void updateUserAge() {
userMapper.updateUserAge(2);
int i = 1 / 0;
}
}
会抛出以下错误:
org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only