gpt4 book ai didi

java - Spring数据库事务未在Db中提交数据

转载 作者:行者123 更新时间:2023-12-02 06:13:33 26 4
gpt4 key购买 nike

我用 spring boot 创建了一个项目。我有 hikariConfig 来创建连接池的数据源,并将 autocommmit 属性设置为 false。使用在 DataSourceTransactionManager 的 @Transaction 注释的方法内运行的 jdbcTemplate 进行批量插入。我无法看到程序执行后数据插入到 Db 中。如果我在 hikariconfig 中将自动提交设置为 true,它就可以正常工作。

@SpringBootApplication

public class Application {

public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

@Component

@EnableTransactionManagement

public class DataSourceConfig {

@Bean (name = "dateSourceForSqlServer")

public DataSource dataSourceForSqlServer () {

HikariConfig hikariConfig = new HikariConfig();
hikariConfig.setConnectionTimeout(10000L);
hikariConfig.setIdleTimeout(10000L);
hikariConfig.setMinimumIdle(1);
hikariConfig.setMaximumPoolSize(1);
hikariConfig.setMaxLifetime(600000L);
hikariConfig.setConnectionTestQuery("select 1");
hikariConfig.setValidationTimeout(4000L);


hikariConfig.setJdbcUrl("jdbc:sqlserver://localhost:1433;database=invt_mgmt");
hikariConfig.setUsername("sa");
hikariConfig.setPassword("sql_server_pass_123");

hikariConfig.setDriverClassName("com.microsoft.sqlserver.jdbc.SQLServerDriver");


hikariConfig.setAutoCommit(false);

return new HikariDataSource(hikariConfig);
}

@Bean (name = "jdbcTemplateForSqlServer")
public JdbcTemplate jdbcTemplateForSqlServer () {
JdbcTemplate jdbcTemplate = new JdbcTemplate();
jdbcTemplate.setDataSource(dataSourceForSqlServer());

return jdbcTemplate;
}

@Primary
@Bean(name = "invtMgmtTxMangerForSqlServer")
public DataSourceTransactionManager transactionManager() {
DataSourceTransactionManager manager = new DataSourceTransactionManager();
manager.setDataSource(dataSourceForSqlServer());
return manager;
}

}


@Component

public class startBean {

@Autowired
private Business Business;

@PostConstruct
public void startApp() throws SQLException {
Business.insertContainerHierarchy();
Business.insertContainerHierarchy();

}
}

@Component

class public Business {

@Autowired
@Qualifier("jdbcTemplateForSqlServer")
private JdbcTemplate jdbcTemplateForSqlServer;

String insertIntStudent = "INSERT INTO student (id, name) Values(?, ?)";

@Transactional(value = "invtMgmtTxMangerForSqlServer")
public void insertContainerHierarchy () throws SQLException {

System.out.println(TransactionSynchronizationManager.isActualTransactionActive());
System.out.println(TransactionSynchronizationManager.getCurrentTransactionName());


Date start = new Date();

for (int i = 0; i < 500; i++) {
System.out.println(i);
jdbcTemplateForSqlServer.batchUpdate(insertIntStudent, new BatchPreparedStatementSetter() {

@Override
public void setValues(PreparedStatement ps, int i) throws SQLException {
ps.setInt(1, i);
ps.setString(2, String.valueOf(i));
}

@Override
public int getBatchSize() {
return 1000;
}
});
}
System.out.println(new Date().getTime() - start.getTime());
}

}

我使用了 TransactionSynchronizationManager.isActualTransactionActive() ,它在执行该方法时返回 true。

Q1。为什么数据没有被插入,事务应该在方法执行后自动提交?

第二季度。如果使用 Spring 事务,数据库连接自动提交值会产生任何影响吗?

第三季度。目前我如何能够在自动提交设置为 true 的情况下插入?

最佳答案

您正尝试从 @PostConstruct 内调用事务包装的代理。方法。对于该 bean,所有初始化可能都已完成,但对于上下文的其余部分则不一定。并非所有代理都可以在此时设置。

我建议实现ApplicationListener<ContextRefreshedEvent>接口(interface)以触发该类内的任何数据创建。这将确保在设置整个上下文后调用它:

@Component
public class OnContextInitialized implements
ApplicationListener<ContextRefreshedEvent> {

@Autowired
private Business Business;

@Override public void onApplicationEvent(ContextRefreshedEvent event) {
Business.insertContainerHierarchy();
Business.insertContainerHierarchy();
}
}

关于java - Spring数据库事务未在Db中提交数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55889089/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com