我尝试将 Spring 的事务管理器与 MyBatis 映射器一起使用,如下所示 在服务的实现中
@Service("myService")
class MyServiceImpl implements MyService
{
@Autowired
private MyMapper myMapper;
@Transactional(
value = "transactionManager",
propagation = Propagation.REQUIRED,
rollbackFor={Exception.class}
)
@Override
public void doStuff() {
myMapper.do1();
myMapper.do2();
throw new RuntimeException();
}
}
其中MyMapper由MyBatis映射。我的实际代码与此略有不同,但我已将其修改为类似于如何在mybatis-spring中使用@Transactional注释?。该服务在控制器类中按以下方式使用。
@Controller
public class MyController {
@Autowired
private MyService myService;
@GetMapping(value = {"/some/url"})
public String someMethod(){
/*
some code
*/
myService.doStuff(); // this line is not wrapped in try/catch block
/*
some code
*/
return "myjsppage";
}
}
据我收集,do1() 和 do2() 中对数据库的更改应该回滚,但由于某种原因它们仍然存在。我错过了什么?这是我的 xml 配置
<mybatis:scan base-package="com.mydomain.mapper" />
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/mydomain" />
<property name="username" value="uuuuuu" />
<property name="password" value="pppppp" />
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="typeAliasesPackage" value="com.mydomain.model"/>
<property name="configLocation" value="WEB-INF/mybatis-config.xml"/>
<property name="mapperLocations" value="classpath*:com/mydomain/mapper/*.xml" />
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.mydomain.mapper" />
</bean>
Spring @Transactional默认情况下在未检查/运行时异常时回滚。属性 rollbackFor 必须仅在针对特定的检查异常/自定义异常/自定义异常时使用
在您的情况下,删除属性 rollbackFor 并检查行为
@Transaction
propagation = Propagation.REQUIRED
这样,您必须尝试使用:
@Transactional(value = "transactionManager", isolation = Isolation.READ_COMMITTED)
它会起作用。
更新:好的,我现在让它工作了。我尝试了许多不起作用的东西,但是清洁解决方案和重新制作可部署确实起到了作用(?为什么会这样,我不知道。
您没有在 Spring 中显式启用事务管理。您可以通过将下面的配置添加到您的 spirng 配置文件中来启用注释驱动的事务管理
<tx:annotation-driven transaction-manager="transactionManager"/>