Article directory
-
- 1 The database engine does not support transactions
- 2 classes are not managed by Spring
- 3 The method is not public
- 4 Self-calling problem
- 5 The data source does not have a transaction manager configured
- 6 Transactions are not supported
- 7 Abnormal was eaten
- 8 Exception type error
- 9 The exception occurred in the newly created thread
1 The database engine does not support transactions
Spring transactions are business layer transactions, and their bottom layer still relies on the transaction support of the database itself. Taking MySQL as an example, its MyISAM engine does not support transaction operations. InnoDB is the engine that supports transactions. InnoDB is generally used to support transactions.
2 classes are not managed by Spring
As shown in the following example:
//@Service
public class OrderServiceImpl implements OrderService {
@Transactional
public void updateOrder(Order order) {
// 业务逻辑
}
}
If you comment out the annotation at this time @Service
, this class will not be loaded into a Bean, then this class will not be Spring
managed, and the transaction will be invalid.
3 The method is not public
@Transactional
It can only be used public
on methods, otherwise the transaction will not be invalidated. If you want to use it on non- public
methods, you can turn on AspectJ
the proxy mode.
4 Self-calling problem
Example 1:
@Service
public class OrderServiceImpl implements OrderService {
public void update(Order order) {
updateOrder(order);
}
@Transactional
public void updateOrder(Order order) {
// 业务逻辑
}
}
update
There are no annotations on the method @Transactional
, call @Transactional
the annotated updateOrder
method, and updateOrder
add a transaction to the method.
Example 2:
@Service
public class OrderServiceImpl implements OrderService {
@Transactional
public void update(Order order) {
updateOrder(order);
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void updateOrder(Order order) {
// 业务逻辑
}
}
In Example 2 , update
the method is added and a new transaction is opened.@Transactional
updateOrder
REQUIRES_NEW
In the above two examples, the transactions will not take effect because they are called by themselves, that is, calling the class's own method without going through Spring's proxy class. By default, the transaction will only take effect when called externally.
5 The data source does not have a transaction manager configured
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
As shown above, even if Spring's transaction management function is used in the code, if Spring's transaction manager is not configured in the project, Spring's transaction will not take effect.
6 Transactions are not supported
propagation
Transaction propagation behavior misconfiguration
Example:
@Service
public class OrderServiceImpl implements OrderService {
@Transactional
public void update(Order order) {
updateOrder(order);
}
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void updateOrder(Order order) {
// 业务逻辑
}
}
Propagation.NOT_SUPPORTED
: Indicates that it will not run as a transaction, and if there is currently a transaction, it will be suspended.
If Propagatio
n is configured not to support running in transaction mode, the transaction will not take effect.
7 Abnormal was eaten
Example:
@Service
public class OrderServiceImpl implements OrderService {
@Transactional
public void updateOrder(Order order) {
try {
// 业务代码
} catch {
}
}
}
If you eat the exception and then don't throw it out, the transaction will not be rolled back!
8 Exception type error
Example:
@Service
public class OrderServiceImpl implements OrderService {
@Transactional
public void updateOrder(Order order) {
try {
// 业务代码
} catch {
throw new Exception("更新错误");
}
}
}
This transaction will not take effect, because the default rollback is: RuntimeException
If you want to trigger the rollback of other exceptions, you need to configure it on the annotation, such as:
@Transactional(rollbackFor = Exception.class)
This configuration is limited to the Throwable exception class and its subclasses.
9 The exception occurred in the newly created thread
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
@Autowired
private RoleService roleService;
@Transactional
public void add(UserModel userModel) throws Exception {
userMapper.insertUser(userModel);
new Thread(() -> {
// 此处发生异常
roleService.save();
}).start();
}
}
@Service
public class RoleService {
@Transactional
public void save() {
// 保存数据
}
}
We can see that in the transaction method add, the transaction method save is called, but the transaction method save is called in another thread. This will result in the two methods not being in the same thread and obtaining different database connections, resulting in two different transactions. If an exception is thrown in the save method, it is impossible to roll back the add method.