【问题标题】:Usertransaction is not working in wildfly with Oracle DBUsertransaction 不适用于 Oracle DB
【发布时间】:2020-08-27 11:47:33
【问题描述】:

我认为事务在 Wildfly 8.2 和 oracle 12.2 上不起作用,以下是我尝试运行的代码:

public static void checkTransaction() throws Exception {

    Statement stmt = null; // Non-transactional statement
    Statement stmtx = null;

    InitialContext initialContext = new InitialContext();

    DataSource ds = (DataSource) initialContext.lookup("jdbc/myDataSource");

    Connection conn = ds.getConnection("USERENAME", "PASSWORD");

    UserTransaction txn = (UserTransaction) new 
    InitialContext().lookup("java:jboss/UserTransaction");


    try {
        stmt = conn.createStatement(); // non-tx statement

        try {
            stmt.executeUpdate("DROP TABLE test_table");
        } catch (Exception e) {
            e.printStackTrace();
            
        }

        try {
            stmt.executeUpdate("CREATE TABLE test_table (a INTEGER,b INTEGER)");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        try {
            System.out.println("Starting top-level tranasction.");

            txn.begin();

            stmtx = conn.createStatement(); // will be a tx-statement

            stmtx.executeUpdate("INSERT INTO test_table (a, b) VALUES (1,2)");

            // First, we try to roll back changes

            txn.rollback(); // rollback 

            txn.begin(); // start second tranaction

            stmtx = conn.createStatement();

            stmtx.executeUpdate("INSERT INTO test_table (a, b) VALUES (3,4)");

            txn.commit(); // committing the second transaction
        } catch (Exception ex) {
            throw new RuntimeException(ex);

        }
    } catch (Exception sysEx) {
        sysEx.printStackTrace();
        
    }
}

数据源配置如下:

 <datasources>
<datasource enabled="true" jndi-name="java:/jdbc/myDataSource" pool-name="DataSourcePool" use-ccm="true">
    <connection-url>jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=host)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=serviceId)))</connection-url>
    <driver>oracle</driver>
    <pool>
        <min-pool-size>4</min-pool-size>
        <max-pool-size>18</max-pool-size>
    </pool>
    <security>
        <security-domain>EncryptedDBPassword</security-domain>
    </security>
    <validation>
        <valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.oracle.OracleValidConnectionChecker"/>
        <check-valid-connection-sql>select 1 from dual</check-valid-connection-sql>
        <validate-on-match>true</validate-on-match>
        <background-validation>true</background-validation>
        <background-validation-millis>30000</background-validation-millis>
        <stale-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.oracle.OracleStaleConnectionChecker"/>
        <exception-sorter class-name="org.jboss.jca.adapters.jdbc.extensions.oracle.OracleExceptionSorter"/>
    </validation>
    <timeout>
        <set-tx-query-timeout>true</set-tx-query-timeout>
        <blocking-timeout-millis>10000</blocking-timeout-millis>
        <idle-timeout-minutes>1</idle-timeout-minutes>
        <query-timeout>120</query-timeout>
        <use-try-lock>0</use-try-lock>
        <allocation-retry>0</allocation-retry>
        <allocation-retry-wait-millis>0</allocation-retry-wait-millis>
    </timeout>
    <statement>
        <share-prepared-statements>false</share-prepared-statements>
    </statement>
</datasource>
<drivers>
    <driver module="com.h2database.h2" name="h2">
        <xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>
    </driver>
    <driver module="com.oracle.ojdbc" name="oracle">
        <driver-class>oracle.jdbc.OracleDriver</driver-class>
    </driver>
</drivers>

发生了什么:

从代码中预计 test_table 将只有一个条目,即 (3,4),因为插入 (1,2) 的前一个事务被回滚,但实际上该表包含 2 行并且两者sqls 已提交。有什么原因导致此交易无效? 这是我为这段代码所遵循的链接:

https://access.redhat.com/documentation/en-us/red_hat_jboss_enterprise_application_platform/7.1/html/development_guide/java_transaction_api_jta#jta_transaction_example

我还假设数据源中 jta 的默认值是 true,不需要显式添加。

【问题讨论】:

    标签: java oracle jboss wildfly jta


    【解决方案1】:

    我能够找出解决这个问题的方法,即针对异步线程。 解决方案是在 UserTransaction.begin() 完成后从 DataSource 获取连接。 这不符合 Wildfly 文档,其中示例显示可以在 Transaction.begin() 之前获取连接,但它不适用于异步线程场景(尽管在 Wildfly 托管 bean 场景中完美工作)。

    Wildfly 交易示例链接:https://access.redhat.com/documentation/en-us/jboss_enterprise_application_platform/6/html/development_guide/jta_transaction_example

    【讨论】:

      【解决方案2】:

      我也有类似的问题。但是,上面当我点击 via Servlet 时。 当我尝试在非 EE 线程中使用事务时出现问题。它不会引发任何异常,但即使我使用了 Usertransaction.rollback(),数据库事务仍会提交。 根据 Wildfly 8 文档,使用 java:jboss/UserTransaction 来获取应该存在的用户事务,并且代码确实获取了 Usertransaction 对象,但实际上并不控制 DB 更改,如上所示。 我的感觉是,我的非 EE 线程在某种程度上不是 Wildfly 托管事务的一部分,但不能有任何文档围绕它。 这里的任何输入都会很棒。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-03-02
        • 2017-02-28
        • 1970-01-01
        • 2017-09-10
        • 2014-11-16
        • 1970-01-01
        • 1970-01-01
        • 2011-03-12
        相关资源
        最近更新 更多