问题描述
我在Spring Boot应用程序中有一个方法,该方法采用SQLite数据库并将其内容插入PostgreSQL数据库。内容必须全部插入或不插入,因此该方法用@Transactional
注释。
SQLite数据库可能很大且缺少索引,因此必须先添加这些索引才能读取其性能。我仍然希望原始文件保持原样,因此首先将文件复制到临时文件夹中,然后在操作完成后将其删除。
// Repository using a JdbcTemplate with an autoconfigured PostgreSQL datasource.
@Autowired MyRepository myRepositry;
@Transactional
public void insert(Path file) {
Path tempFile = copyToTempDir(file);
try {
// Setup connection to SQLite database
SQLiteDataSource dataSource = new SQLiteDataSource();
dataSource.setUrl("jdbc:sqlite:" + tempFile);
JdbcTemplate sqlite = new JdbcTemplate(dataSource);
addIndex(sqlite);
while(hasMoreData(sqlite)) {
MyData data = readData(sqlite);
myRepository.insert(data);
}
} catch(Exception ex) {
// handle it..
} finally {
deleteCopy(tempFile);
}
}
问题在于删除finally子句中的SQLite副本。由于我们仍在事务中,因此数据库连接不会关闭,并且操作系统(无论如何是Windows)都拒绝删除文件。如果我删除@Transactional
批注,一切正常。
我尝试将与sqlite JdbcTemplate交互的方法包装在TransactionTemplate
中。如我所料,将其传播行为设置为NEVER
确实会导致异常,但是使用NOT_SUPPORTED
或REQUIRES_NEW
仍会锁定文件。
@Autowired DataSourceTransactionManager transactionManager;
private MyData readData(JdbcTemplate sqlite) {
TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_NOT_SUPPORTED);
return transactionTemplate.execute(status -> {
// read data...
});
}
那么我可以通过某种配置以某种方式将SQLite文件与事务管理隔离,还是必须使用原始JDBC来确保Spring不参与其中?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)