Como implementar transações?

Para implementar transações devem ser utilizados os seguintes recursos:

IMecanismoPersistencia
MecanismoPersistenciaBDR
RepositorioException

Os quais devem ser utilizados como no seguinte exemplo:

    /**
     * Fachada do sistema
     */
    public class Banco {
    
        ...
        private CadastroContas contas;
        private IMecanismoPersistencia mp;
        ...
        
        public Banco(..., RepositorioContas repContas,IMecanismoPersistencia mp) {
            ...
            this.contas = new CadastroContas(repContas);
            this.mp = mp;
            mp.conectar();
        }
        
        /**
         * Ao invés de implementar este método, você pode colocar 
         * uma chamada para o desconectar a partir da interface,
         * imediatamente antes de fechar o sistema.
         */
        public void finalize() {
            try {
                mp.desconectar();
            } catch(RepositorioException ex) {
                ex.printStackTrace();
            }                
        }
        ...
        
        public cadastrar(Conta conta) throws ContaJaCadastradaException {
            try {
                mp.iniciarTransacao();
                contas.cadastrar(conta);
                mp.confirmarTransacao();
            } catch(ContaJaCadastradaException ex) {
                mp.cancelarTransacao();
            }
        }   
        ...
    }
    

Quem cria a classe fachada deve passar como parâmetro uma implementação do mecanismo de persistência, como é feito com as coleções de dados (repositorios).


      
    /**
     * Exemplo de coleção de dados
     */
    public class RepositorioContasBDR implements RepositorioContas {
    
        private MecanismoPersistenciaBDR mp;
        ...
        
        public RepositorioContasBDR() {
            ...
            this.mp = MecanismoPersistenciaBDR.getInstance();
        }
        
        ...
        
        public inserir(Conta conta) {
            String sql = null;
            PreparedStatement pstmt = null; // ou Statement stmt = null;
            try {
                sql = ...;
                pstmt = (PreparedStatement) mp.getCanalComunicacao(sql); // ou stmt = (Statement) mp.getCanalComunicacao();
                ...
            } catch(SQLException ex) {
                throw new RepositorioException(ex);
            } finally {
                pm.liberarCanalComunicacao();
            }
        }   
        ...
    }