Java Spring TransactionManager-提交不起作用
我正在尝试创建基于Spring的解决方案,以便在MySQL 5.5服务器上运行SQL查询批处理。 我所说的“查询”是指编译的任何SQL语句,因此SQL批处理作业可以包含例如多个CREATETABLE、DELETE和INSERT语句 我正在为此目的使用 我对transactionManager进行了如下配置Java Spring TransactionManager-提交不起作用,java,jdbc,transactions,spring-batch,transactionmanager,Java,Jdbc,Transactions,Spring Batch,Transactionmanager,我正在尝试创建基于Spring的解决方案,以便在MySQL 5.5服务器上运行SQL查询批处理。 我所说的“查询”是指编译的任何SQL语句,因此SQL批处理作业可以包含例如多个CREATETABLE、DELETE和INSERT语句 我正在为此目的使用 我对transactionManager进行了如下配置 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSour
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
我的DAO类的方法配置为
@Transactional(propagation = Propagation.REQUIRES_NEW)
我循环一组SQL语句,每次使用一条SQL语句调用该方法。
方法内部的处理非常简单,如下所示:
simpleJdbcTemplate.getJdbcOperations().execute(sql);
我希望当DAO方法完成时,我会在DB中看到结果。
然而,似乎只有当Spring作业执行完成时,结果才会在DB中可用
我尝试在DAO方法中执行提交:
@Transactional(propagation = Propagation.REQUIRES_NEW)
private void executeSingleQuery(String sql) {
PlatformTransactionManager transactionManager = (PlatformTransactionManager)context.getBean("transactionManager");
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(Propagation.REQUIRED.ordinal());
TransactionStatus status = transactionManager.getTransaction(def);
try {
// execute your business logic here
log.info("about to execute SQL query[" + sql + "]");
simpleJdbcTemplate.getJdbcOperations().execute(sql);
} catch (Exception e) {
log.info("SQL query was not committed due to exception and was marked for rollback");
transactionManager.rollback(status);
}
transactionManager.commit(status);
if (transactionManager.getTransaction(null).isRollbackOnly()
&& transactionManager.getTransaction(null).isCompleted()) {
log.info("SQL query commited!");
} else {
log.info("SQL query was not committed due to: 1) the transaction has been marked for rollback " +
"2) the transaction has not completed for some reason");
}
log.info("the query has completed");
}
我调试了Spring代码,发现我从DAO方法调用的提交是由TransactionTemplate执行的(流到达行this.transactionManager.commit(status);
并且无异常地通过)
如果您能给我一些建议,让DAO方法在每次调用时都提交(在执行每个SQL语句后提交),我将不胜感激。您不能代理私有方法。i、 e.此处的@Transactional无效。将该方法拉到父接口,它应该可以工作。除非启用了不推荐的proxyTargetClass设置。从同一类中调用
executeSingleQuery()
时,您不会通过代理进行操作,因此事务性批注将无效
您正在混合声明性事务和编程性事务,可能希望REQUIRES\u NEW
,以便可以删除无意义的@Transactional
注释并使用传播。在设置DefaultTransactionDefinition
时,REQUIRES\u NEW
另外,您可能希望在
try
块内移动transactionManager.commit(status)
,当前代码回滚,然后在发生异常时尝试提交。我们使用了@Rollback(value=false)
注释,解决了您面临的问题。将DAO方法更改为public-同样的问题将方法拉到父接口有助于解决此问题。舒克兰!:)@事务性注释负责提交。在您的代码中,我想您不需要引用事务管理器,也不需要显式提交更改。谢谢,我支持您的答案,因为它很有帮助(部分)。然而,我不能接受两个答案-马德托是第一个回答。。。
@Transactional(propagation = Propagation.REQUIRES_NEW)
private void executeSingleQuery(String sql) {
PlatformTransactionManager transactionManager = (PlatformTransactionManager)context.getBean("transactionManager");
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(Propagation.REQUIRED.ordinal());
TransactionStatus status = transactionManager.getTransaction(def);
try {
// execute your business logic here
log.info("about to execute SQL query[" + sql + "]");
simpleJdbcTemplate.getJdbcOperations().execute(sql);
} catch (Exception e) {
log.info("SQL query was not committed due to exception and was marked for rollback");
transactionManager.rollback(status);
}
transactionManager.commit(status);
if (transactionManager.getTransaction(null).isRollbackOnly()
&& transactionManager.getTransaction(null).isCompleted()) {
log.info("SQL query commited!");
} else {
log.info("SQL query was not committed due to: 1) the transaction has been marked for rollback " +
"2) the transaction has not completed for some reason");
}
log.info("the query has completed");
}