Java Spring(5.0.8)事务和jdbcTemplate
我想要一个经典的事务行为:创建a,创建b,如果创建b失败,回滚创建a。Java Spring(5.0.8)事务和jdbcTemplate,java,spring,transactions,jdbctemplate,Java,Spring,Transactions,Jdbctemplate,我想要一个经典的事务行为:创建a,创建b,如果创建b失败,回滚创建a。 “没那么难,在方法上添加@Transactional spring注释。” 我也是。但它不起作用。 我使用的是SpringMVC5.0.8(与SpringTX相同的版本号,在下面的pom.xml中)。数据库是mysql v.5.7.23 首先是我的配置/代码,然后是很多人都会遇到的一些冗余错误 这里是一个服务级别方法 @Transactional(propagation = Propagation.REQUIRED, rol
“没那么难,在方法上添加@Transactional spring注释。”
我也是。但它不起作用。
我使用的是SpringMVC5.0.8(与SpringTX相同的版本号,在下面的pom.xml中)。数据库是mysql v.5.7.23
首先是我的配置/代码,然后是很多人都会遇到的一些冗余错误 这里是一个服务级别方法
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public B createB(B b) {
//some logic to create a, instance of A
aDao.saveA(a);
//some logic to create b, instance of B
return bDao.saveB(b);
}
以下是数据源、jdbctemplate和事务管理器配置:
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getRequiredProperty("jdbc.driverClassName"));
dataSource.setUrl(env.getRequiredProperty("jdbc.url"));
dataSource.setUsername(env.getRequiredProperty("jdbc.username"));
dataSource.setPassword(env.getRequiredProperty("jdbc.password"));
return dataSource;
}
@Bean
public JdbcTemplate jdbcTemplate(DataSource dataSource) {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
jdbcTemplate.setResultsMapCaseInsensitive(true);
return jdbcTemplate;
}
@Bean("transactionManager")
public PlatformTransactionManager getTransactionManager(DataSource dataSource) {
DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
dataSourceTransactionManager.setDataSource(dataSource);
return dataSourceTransactionManager;
}
以下是我的pom.xml的一部分:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
编辑1结束
现在,在互联网上的许多地方都可以找到可能的答案,大部分是:
- 回滚仅适用于未检查的异常(=运行时异常)。
BDao抛出一个自定义运行时异常。我在@Transactionnal定义中添加了“rollboor=Exception.class” - 由于内部方式@Transactional works(AOP),您必须从方法外部调用它。
在这种情况下,“createB”方法直接从另一个类调用(目前仅从控制器调用) - 您必须用这个精确的名称定义“transactionManager”。
起初我没有事务管理器。当我意识到这一点时,我觉得自己有点笨。但即使有一个事务管理器,有了这个确切的名称,它也不起作用 - 我甚至发现有人需要添加propagation=propagation.REQUIRED,所以我也这么做了,但这并没有改变任何事情
- 数据库必须支持事务、回滚…
这是一个mysql,所有表上都有InnoDB引擎,根据相同的答案,它支持mysql
现在,我没有任何其他想法,也无法在internet上找到其他想法,所以我在这里。使用事务时,请确保您已在
@配置上使用@EnableTransactionManagement
启用了事务
如果没有这个注释,您基本上是在没有事务的情况下运行的,这使得每个操作都在自己的事务中运行。将DAO添加到您的帖子中。另外1.它已经是运行时异常
,因此不应该需要。3.如果有一个平台TransactionManager
名称并不重要。4.这就是定义谢谢你抽出时间:),我在我的帖子中添加了DAO。1)我也这么认为,但可以肯定的是,我添加了它…3和4:谢谢你的澄清,我不知道。你的配置类中有@EnableTransactionManagement
吗?好问题!我确实知道它存在,我在研究过程中看到了它的xml等价物,但从未看到过注释,所以我认为它是ena默认流血。不用担心,非常感谢!如果你想发布答案,我很乐意接受。
@Repository
public class SqlADao implements ADao {
private static final String CREATE_A = "INSERT INTO a(id, param1,
param2) VALUES(?, ?, ?)";
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public Addressee saveA(A a) {
try {
String id = UUID.randomUUID().toString();
a.setId(id);
jdbcTemplate.update(CREATE_A, id, a.getParam1(),
addressee.getParam2());
return a;
} catch (Exception e) {
throw new DaoException("Exception while accessing data.", e);
}
}
}
@Repository
public class SqlBDao implements BDao {
private static final String CREATE_B = "INSERT INTO b(id, param1,
param2, param3, param4, param5, param6) VALUES(?, ?, ?, ?, ?, ?, ?)";
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public Account saveAccount(Account account) {
try {
String id = UUID.randomUUID().toString();
b.setId(id);
jdbcTemplate.update(CREATE_B, id, b.getParam1(),
Date.valueOf(b.getParam2LocalDate()), b.getParam3,
b.getParam4(), b.getParam5(),b.getParam6());
return b;
} catch (Exception e) {
throw new DaoException("Exception while accessing data.", e);
}
}
}