[ 
http://issues.apache.org/jira/browse/DERBY-421?page=comments#action_12317372 ] 

Daniel John Debrunner commented on DERBY-421:
---------------------------------------------

State information is kept in BrokeredConnection for this reason (comment in 
BrokeredConnection)
        /**
                Maintain state as seen by this Connection handle, not the state
                of the underlying Connection it is attached to.
        */

To expand on that, an application getting a Connection C from an 
XADataSource/XAConnection can use C in local mode or in global mode. The 
application can set  C's state with various setXXX calls, and thus the 
applcation has expectation of what the state is. When C is connected to a local 
transaction, the state of the connection needs to match any state set by the 
application. When C is attached an existing  global transaction the C's state 
needs to match that of the exsiting transaction, not the state as expected by 
the application. Then when reverting to local mode,  the state needs to be 
reset as the application expects it.
Here's a simple example.

c.setReadOnly(true);
// do some local work

// now attach to an existing global transaction
c.isReadOnly(); // returns false as the transaction has included modifications

// now detach from the global transaction

// This is the critical point
c..isReadOnly();  // needs to return true because that's what the application 
is expecting

Thus the BrokeredConnection maintains the state that it needs to set on the new 
local underlying EmbedConnection object to ensure its state is in sync with the 
application's expectation. This is also because the Derby embedded 
implementation always creates a new EmbedConnection object when switching from 
global to local.

> starting an XA transaction resets the isolation level set with SET CURRENT 
> ISOLATION
> ------------------------------------------------------------------------------------
>
>          Key: DERBY-421
>          URL: http://issues.apache.org/jira/browse/DERBY-421
>      Project: Derby
>         Type: Sub-task
>     Reporter: Kathey Marsden

>
> When an XA Transaction is started the isolation level set with SET CURRENT 
> ISOLATION gets reset to CS.
> Embedded setTransactionIsolation  does not have this problem but this problem 
> is the root cause of DERBY-414 because client implements 
> setTransactionIsolation by sending SET CURRENT ISOLATION
> $ java TestSetCurrentIsolation
> Database product: Apache Derby
> Database version: 10.2.0.0 alpha
> Driver name:      Apache Derby Embedded JDBC Driver
> Driver version:   10.2.0.0 alpha
> SET CURRENT ISOLATION = UR
> CURRENT ISOLATION: UR
> getTransactionIsolation:TRANSACTION_READ_UNCOMMITTED:1
> Isolation level after xa start
> CURRENT ISOLATION: CS
> getTransactionIsolation:TRANSACTION_READ_COMMITTED:2
> $
> import java.sql.*;
> import javax.sql.*;
> import javax.transaction.xa.*;
> public class TestSetCurrentIsolation
> {
>     public static void main(String[] args) throws Throwable
>     {
>         try
>         {
>              final org.apache.derby.jdbc.EmbeddedXADataSource ds =
>              new org.apache.derby.jdbc.EmbeddedXADataSource();
>              ds.setDatabaseName("C:\\drivers\\derby\\databases\\SCHEDDB");
>              ds.setUser("dbuser1");
>              ds.setPassword("******");
>             XAConnection xaConn = ds.getXAConnection();
>             Connection conn = xaConn.getConnection();
>             conn.setAutoCommit(true);
>             System.out.println("Database product: " + 
> conn.getMetaData().getDatabaseProductName());
>             System.out.println("Database version: " + 
> conn.getMetaData().getDatabaseProductVersion());
>             System.out.println("Driver name:      " + 
> conn.getMetaData().getDriverName());
>             System.out.println("Driver version:   " + 
> conn.getMetaData().getDriverVersion());
>             Statement stmt = conn.createStatement();
>             System.out.println("SET CURRENT ISOLATION = UR");
>             stmt.executeUpdate("SET CURRENT ISOLATION = UR");
>             showIsolationLevel(conn);
>             conn.setAutoCommit(false);
>             XAResource xaRes = xaConn.getXAResource();
>             Xid xid = new TestXid(1,(byte) 32, (byte) 32);
>             xaRes.start(xid, XAResource.TMNOFLAGS);
>             System.out.println("Isolation level after xa start");
>             showIsolationLevel(conn);
>             
>             xaRes.end(xid, XAResource.TMSUCCESS);
>             xaRes.rollback(xid);
>             conn.close();
>             xaConn.close();
>         }
>         catch (SQLException sqlX)
>         {
>             System.out.println("Error on thread 1.");
>             do sqlX.printStackTrace();
>             while ((sqlX = sqlX.getNextException()) != null);
>         }
>         catch (Throwable th)
>         {
>             System.out.println("Error on thread 1.");
>             do th.printStackTrace();
>             while ((th = th.getCause()) != null);
>         }
>     }
>       /**
>        * @param conn
>        * @throws SQLException
>        */
>       private static void showIsolationLevel(Connection conn) throws 
> SQLException {
>               PreparedStatement ps = conn.prepareStatement("VALUES CURRENT 
> ISOLATION");
>               ResultSet rs = ps.executeQuery();
>               //ResultSet rs = conn.createStatement().executeQuery("VALUES 
> CURRENT ISOLATION");
>               rs.next();
>               System.out.println("CURRENT ISOLATION: " +  rs.getString(1));
>               System.out.println("getTransactionIsolation:" + 
>                                       
> getIsoLevelName(conn.getTransactionIsolation()));                             
>                   
>       }
>       
>       public static String getIsoLevelName(int level)
>       {
>               switch (level) {
>                       case java.sql.Connection.TRANSACTION_REPEATABLE_READ:
>                               return "TRANSACTION_REAPEATABLE_READ:" + level;
>                                       
>                       case java.sql.Connection.TRANSACTION_READ_COMMITTED:
>                               return "TRANSACTION_READ_COMMITTED:" + level;
>                       case java.sql.Connection.TRANSACTION_SERIALIZABLE:
>                               return "TRANSACTION_SERIALIZABLE:" + level;
>                       case java.sql.Connection.TRANSACTION_READ_UNCOMMITTED:
>                               return "TRANSACTION_READ_UNCOMMITTED:" + level;
>               }
>               return "UNEXPECTED_ISO_LEVEL";
>       }
> }

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira

Reply via email to