不同 OracleDB 连接之间的共享事务
经过几天对这个问题的调查,我决定提交这个问题,因为正在发生的事情显然没有意义。
案例
我的计算机配置了本地 Oracle Express 数据库。我有一个JAVA项目,其中包含几个JUnit测试,这些测试扩展了一个父类(我知道这不是一个“最佳实践”),它在@Before方法中打开OJDBC连接(使用10个连接的静态Hikari连接池),并在@After回滚它。
public class BaseLocalRollbackableConnectorTest {
private static Logger logger = LoggerFactory.getLogger(BaseLocalRollbackableConnectorTest.class);
protected Connection connection;
@Before
public void setup() throws SQLException{
logger.debug("Getting connection and setting autocommit to FALSE");
connection = StaticConnectionPool.getPooledConnection();
}
@After
public void teardown() throws SQLException{
logger.debug("Rollback connection");
connection.rollback();
logger.debug("Close connection");
connection.close();
}
StacicConnectionPool
public class StaticConnectionPool {
private static HikariDataSource ds;
private static final Logger log = LoggerFactory.getLogger(StaticConnectionPool.class);
public static Connection getPooledConnection() throws SQLException {
if (ds == null) {
log.debug("Initializing ConnectionPool");
HikariConfig config = new HikariConfig();
config.setMaximumPoolSize(10);
config.setDataSourceClassName("oracle.jdbc.pool.OracleDataSource");
config.addDataSourceProperty("url", "jdbc:oracle:thin:@localhost:1521:XE");
config.addDataSourceProperty("user", "MyUser");
config.addDataSourceProperty("password", "MyPsw");
config.setAutoCommit(false);
ds = new HikariDataSource(config);
}
return ds.getConnection();
}
}
此项目有数百个测试(不是并行的),这些测试使用此连接(在本地主机上)通过 Sql2o 执行查询(插入/更新和选择),但事务和连接绑定仅在外部管理(通过上面的测试)。数据库完全为空,无法进行 ACID 测试。
因此,预期的结果是将某些内容插入到数据库中,进行断言,然后回滚。这样,第二个测试将找不到上一个测试添加的任何数据,以保持隔离级别。
问题一起运行所有测试(按顺序),90%的测试可以正常工作。10%的一个或两个测试随机失败,因为数据库中有以前的测试的脏数据(例如,重复的唯一数据)。查看日志,先前测试的回滚已正确完成。实际上,如果我检查数据库,它是空的)如果我在具有较高性能但具有相同JDK,相同Oracle DB XE的服务器中执行此测试,则此故障率增加到50%。
这很奇怪,我不知道,因为测试之间的连接是不同的,每次都调用回滚。JDBC 隔离级别是 READ COMMITED,因此即使我们使用相同的连接,即使使用相同的连接,也不应产生任何问题。所以我的问题是:为什么会这样?你有什么想法吗?JDBC 回滚是否如我所知是同步的,或者在某些情况下,即使它尚未完全完成,它也可以继续进行?
这些是我的主要数据库参数:处理 100 个会话 172 个事务 189