哪些修饰符会导致事务失效?
时间: 2023-06-06 21:07:32 浏览: 85
在关系型数据库中,事务可以使用以下修饰符来控制对数据库的操作:
1. COMMIT
2. ROLLBACK
3. SAVEPOINT
但是,如果在事务中使用以下修饰符,将导致事务失效:
1. ALTER
2. CREATE
3. DROP
4. RENAME
5. TRUNCATE
因此,在这些修饰符出现的情况下,事务将自动回滚,不会提交。
相关问题
mybatis-plus @DS 注解失效
### MyBatis-Plus 中 `@DS` 注解失效解决方案
#### 数据源切换机制分析
在 Spring Boot 和 MyBatis-Plus 的多数据源配置中,`@DS` 注解用于指定当前操作应使用的数据库连接。然而,在某些情况下,此注解可能无法正常工作。
当遇到 `@DS` 注解失效的情况时,通常是因为事务管理器的影响或是访问控制符的问题。具体来说:
- 如果方法被声明为 `protected` 或者其他非公共访问级别,则可能导致 `@DS` 注解不生效[^4]。
- 当存在全局或局部事务时,可能会覆盖掉由 `@DS` 设置的数据源上下文,从而导致实际查询仍然指向默认数据源[^3]。
#### 解决方案一:调整访问修饰符
对于因访问修饰符引起的 `@DS` 失效问题,可以尝试将受影响的方法改为 `public` 访问级别。这有助于确保 AOP 切面能够正确识别并处理这些带有 `@DS` 注解的方法调用。
```java
// 修改前
protected void someMethod() {
// ...
}
// 修改后
public void someMethod() {
// ...
}
```
#### 解决方案二:分离事务边界
针对由于事务引起的数据源切换失败情况,建议重新设计业务逻辑流程,使得涉及不同数据源的操作不在同一个事务范围内完成。可以通过创建独立的服务类来分别封装对各个库的操作,并各自加上合适的事务属性。
```java
@Service
@Transactional(propagation = Propagation.REQUIRES_NEW)
public class DataSourceAService {
public void operateOnDataSourceA(){
// 对 data source A 进行操作...
}
}
@Service
@Transactional(propagation = Propagation.REQUIRES_NEW)
public class DataSourceBService {
public void operateOnDataSourceB(){
// 对 data source B 进行操作...
}
}
```
此外,还可以考虑使用编程方式手动开启新事务,以绕过原有事务对外部数据源的选择干扰。
#### 解决方案三:自定义数据源切换策略
如果上述两种办法都不能解决问题,那么就需要深入研究现有的动态数据源实现原理,甚至编写自己的数据源路由算法。通过继承 `AbstractRoutingDataSource` 类来自定义数据源选择规则,并将其注册到应用程序上下文中作为主要数据源提供者。
```java
@Component
public class DynamicDataSource extends AbstractRoutingDataSource {
private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
@Override
protected Object determineCurrentLookupKey() {
return getContext();
}
public static void setContext(String dataSourceName){
contextHolder.set(dataSourceName);
}
public static String getContext(){
return Optional.ofNullable(contextHolder.get()).orElse("default");
}
public static void clearContext(){
contextHolder.remove();
}
}
```
最后,在每次需要改变目标数据源之前调用 `DynamicDataSource.setContext()` 方法传入相应的名称;完成后记得清理线程变量以防内存泄漏。
阅读全文