Взгляните на шаблон проектирования обратного вызова . По сути, вы работаете с экземпляром интерфейса в вашем коде, и его реализация обрабатывает ваши исключения / транзакции БД. Вы можете иметь что-то вроде:
public interface DatabaseQuery {
public void execute();
}
public class OracleQuery implements DatabaseQuery {
@Override
public void execute() {
//run query, catch exceptions etc.
}
}
public class PostgresQuery implements DatabaseQuery {
@Override
public void execute() {
//run query, catch exceptions etc.
}
}
Затем в своем коде, где вам нужно выполнять транзакции базы данных, вы передаете экземпляр этого интерфейса:
public class TestQuery {
DatabaseQuery query;
public TestQuery(DatabaseQuery query) {
this.query = query;
}
public void SomeDatabaseStuff() {
//some code
// need to work with the db
query.execute();
//some more code
}
}
Вам не нужно беспокоиться о том, будет ли это Oracle или Postgres, реализация справится с этим за кулисами.