2011-02-09 9 views
39

Connection.setTransactionIsolation(int) advierte:¿Cómo iniciar una transacción en JDBC?

Nota: Si este método se llama durante una transacción, el resultado es definido por la implementación.

Esto abre la pregunta: ¿cómo comienza una transacción en JDBC? Está claro cómo finalizar una transacción, pero no cómo comenzarla.

Si Connection comienza dentro de una transacción, ¿cómo se supone que invoquemos Connection.setTransactionIsolation(int) fuera de una transacción para evitar el comportamiento específico de la implementación?

Respuesta

37

responder a mi propia pregunta:

  • conexiones JDBC comienzan con el modo de confirmación automática está activada, donde cada sentencia SQL está implícitamente demarcada con una transacción.
  • Los usuarios que deseen ejecutar sentencias múltiples por transacción deben cumplir auto-commit off.
  • Al cambiar el modo de confirmación automática se desencadena una confirmación de la transacción actual (si hay una activa).
  • Connection.setTransactionIsolation() pueden invocarse en cualquier momento si la confirmación automática está habilitada.
  • Si la confirmación automática está deshabilitada, Connection.setTransactionIsolation() solo se puede invocar antes o después de una transacción. Invocarlo en medio de una transacción conduce a un comportamiento indefinido.

Fuentes:

17

le sugiero que lea this verá

Por lo tanto, la primera llamada de setAutoCommit (falso) y cada llamada de commit() implícitamente marcar el inicio de una transacción . Las transacciones pueden ser deshecha antes de que sean cometidos por llamando

Editar:

Comprobar la documentación oficial sobre las transacciones JDBC

Cuando se crea una conexión, es en auto modo de compromiso. Esto significa que cada instrucción SQL individual se trata como una transacción y es comprometido automáticamente justo después de que se ejecuta. (Para ser más preciso, el valor predeterminado es que una declaración SQL se confirme cuando se completa , no cuando se ejecuta. Una declaración se completa cuando se recuperaron todos los de sus conjuntos de resultados y los recuentos actualizados. En casi todos los casos, sin embargo, una declaración se ha completado, y por lo tanto comprometidos, justo después de que se ejecute.)

la manera de permitir que dos o más declaraciones a agruparse en una transacción es desactivar el modo auto-commit . Esto se demuestra en el siguiente código, donde con es una conexión activa:

con.setAutoCommit (falso);

Fuente: JDBC Transactions

+2

no puedo encontrar la cita antes mencionada en la página vinculado a. Además, preferiría encontrar una cita en la especificación JDBC en oposición a alguna cita sin fuente en devx (suponiendo que no tenga ninguna fuente, eso es). – Gili

+0

+1 para esceptical !! – Necronet

16

JDBC demarca implícitamente cada consulta/actualización se realiza en el marco de una transacción. Puede personalizar este comportamiento llamando al setAutoCommit (falso) para desactivar el modo de confirmación automática y llamar al commit()/rollback() para indicar el final de una transacción. Pesudo código

try 
{ 
    con.setAutoCommit(false); 

    //1 or more queries or updates 

    con.commit(); 
} 
catch(Exception e) 
{ 
    con.rollback(); 
} 
finally 
{ 
    con.close(); 
} 

Ahora, hay un tipo en el método que ha mostrado. Debe ser setTransactionIsolation (nivel int) y no es la API para la demarcación de transacciones.Gestiona cómo/cuándo los cambios realizados por una sola operación se hacen visibles a otras operaciones simultáneas, el "I" en ÁCIDO (http://en.wikipedia.org/wiki/Isolation_(database_systems))

+0

¿Dónde dice que setAutoCommit (falso) denota el inicio de una transacción? – Gili

+0

Su respuesta no indica cuándo es seguro invocar setTransactionIsolation(). ¿Por qué Javadoc lee "Nota: si se llama a este método durante una transacción, el resultado está definido por la implementación." – Gili

+0

un consejo más: sea agradable y restablezca el estado anterior de AutoCommit: boolean previousAutoCommit = conn.getAutoCommit(); try {...} finally {conn.setAutoCommit (previousAutoCommit)} – voho

9

En realidad, this page from the JDBC tutorial sería una mejor lectura.
Obtendrá su conexión, establecerá su nivel de aislamiento y luego realizará sus actualizaciones y cosas, y luego confirmará o retrotraerá.

+2

Incluso el tutorial no aborda este problema de forma explícita. Contiene frases confusas como: "Es aconsejable desactivar el modo de confirmación automática solo durante el modo de transacción". ¿Qué es un "modo de transacción"? – Gili

+0

@Gili ¿Dónde te mordieron? –

2

Tal vez esto responder a su pregunta: Sólo puede tener una transacción por conexión. Si la confirmación automática está activada (por defecto), cada selección, actualización, eliminación se iniciará automáticamente y confirmará (o revertirá) una transacción. Si desactiva el autocommit, inicia una transacción "nueva" (significa que la confirmación o reversión no se realizará automáticamente). Después de algunas declaraciones, puede invocar confirmación o reversión, que finaliza la transacción actual y automáticamente inicia una nueva. No puede haber dos transacciones activas abiertas en una conexión JDBC en JDBC puro.

0

Puede utilizar estos métodos para la transacción:

  1. debe crear el objeto de conexión como con
  2. con.setAutoCommit(false);
  3. sus consultas
  4. si es verdad todo lo con.commit();
  5. demás con.rollback();
+1

Eso realmente no agrega nada nuevo que otras respuestas no cubrieron ... –

1

Startingly, puede ejecutar manualmente una transacción, si desea dejar su conexión en "setAutoCommit (verdadero)" modo pero todavía quiere una transacción:

try (Statement statement = conn.createStatement()) { 
     statement.execute("BEGIN"); 
     try { 
     // use statement ... 
     statement.execute("COMMIT"); 
     } 
     catch (SQLException failure) { 
     statement.execute("ROLLBACK"); 
     } 
    } 
Cuestiones relacionadas