@Transactional注解失效
@Transactional注解失效
1、看数据库表的引擎是否支持事务
对于MySQL数据库,常用的引擎有MYISAM和InnoDB,但MYISAM引擎不支持事务操作,InnoDB引擎才支持事务操作,所以可以先查看表的引擎是否支持事务。
2、看是否对发生的异常进行了捕获
如
@Service
@Transactional
public class UserService {
@Autowired
private UserDao userDao;
public void transferMoney(){
try {
userDao.decrOne();
int a = 10/0;
userDao.incrOne();
}catch (ArithmeticException e) {
e.printStackTrace();
}
}
}
此时异常已经被捕获,所以事务不会生效
@Service
@Transactional
public class UserService {
@Autowired
private UserDao userDao;
public void transferMoney(){
try {
userDao.decrOne();
int a = 10/0;
userDao.incrOne();
}catch (NullPointerException e) {
e.printStackTrace();
}
}
}
由于此时发生的异常为ArithmeticException,但是捕获的异常为NullPointerException,所以此时事务是会生效并且回滚。
如果是在service层抛出异常,而在调用service的方法上(如controller层)捕获了异常,则事务仍然能够回滚
3、看是否开启了事务注解
<!--创建事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="datasource"/>
</bean>
<!--开启事务注解-->
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
4、看方法的访问修饰符是不是public
@Transactional注解只能对可见度为public的方法有效,如果使用protected等修饰符,事务不会起作用。
@Service
@Transactional
public class UserService {
@Autowired
private UserDao userDao;
//访问修饰符为protected,注解不生效
protected void transferMoney(){
userDao.decrOne();
int a = 10/0;
userDao.incrOne();
}
}
5、看是否被未注解的方法调用
如
@Service
public class UserService {
@Autowired
private UserDao userDao;
@Transactional
public void transferMoney(){
userDao.decrOne();
int a = 10/0;
userDao.incrOne();
}
public void test() {
transferMoney();
}
}
test方法没有@transactional注解,此时调用transferMoney方法,则transferMoney方法发生异常之后不会回滚。