Atomikos分布式事务异常

 

springboot项目通过内嵌的tomcat部署,在使用jta事务时报错,如何在只修改AtomikosConfiguration或Trans类的情况下使其正常运行???

[2021-03-10 15:17:29.197] - 14692 警告 [http-nio-8080-exec-2] --- com.atomikos.datasource.xa.XAResourceTransaction: XA resource 'ds1': resume for XID '31302E372E34352E35382E746D313631353336303634393135343030303031:31302E372E34352E35382E746D31' raised -6: the XA resource did not expect this command in the current context
oracle.jdbc.xa.OracleXAException
    at oracle.jdbc.xa.OracleXAResource.checkError(OracleXAResource.java:1110)
    at oracle.jdbc.xa.client.OracleXAResource.start(OracleXAResource.java:240)
    at com.atomikos.datasource.xa.XAResourceTransaction.resume(XAResourceTransaction.java:297)

 

代码如下:

@Slf4j
@RestController
public class TestController {
    @RequestMapping("/test")
    public String test() throws Exception {
        UserTransaction trans = null;
        try {
            TestUtil.lock();
            trans = Trans.getUserTransaction();
            trans.begin();
            UserSession user = new UserSession("111");
            TestUtil.addSession(user);
            trans.commit();
        } catch (Exception e) {
            log.error("异常", e);
            if (trans != null) {
                trans.rollback();
            }
            return "fail";
        }
        return "success";
    }
}
@Slf4j
public class TestUtil {
    public static void addSession(UserSession user) throws Exception {
        PreparedStatement pst = null;
        Connection conn = null;
        String sql = "insert into t_user_sessions(user_sessions_id,user_id,ip,session_id,login_time,status) values("
                + System.currentTimeMillis() + ",?,?,?,sysdate,1)";
        try {
            conn = Trans.getConnection();
            pst = conn.prepareStatement(sql);
            int pos = 1;
            pst.setString(pos++, user.getUserId());
            pst.setString(pos++, user.getIp());
            pst.setString(pos++, user.getSessionId());
            pst.executeUpdate();
        } catch (Exception e) {
            throw e;
        } finally {
            close(null, pst, conn);
        }
    }

    public static void lock() throws Exception {
        PreparedStatement pst = null;
        ResultSet rs = null;
        Connection conn = Trans.getConnection();
        try {
            String sql = "select batch_cfg_id,status from gp_pol_prod_cfg where batch_cfg_id = 621 and policy_id = 96157426 for update of status nowait";
            pst = conn.prepareStatement(sql);
            rs = pst.executeQuery();
        } catch (Exception e) {
            log.error("加锁失败", e);
            throw e;
        } finally {
            close(rs, pst, conn);
        }
    }

    private static void close(ResultSet rs, PreparedStatement pst, Connection conn) {
        try {
            if (rs != null) {
                rs.close();
            }
            if (pst != null) {
                pst.close();
            }
            if (conn != null) {
                conn.close();
            }
        } catch (Exception e) {
            log.error("关闭资源发生异常", e);
        }
    }
}
public class Trans {

    public static Connection getConnection() throws NamingException, SQLException {
        DataSource ds = (DataSource) SpringContextUtil.getApplicationContext().getBean("atomDataSource");
        Connection conn = ds.getConnection();
        return conn;
    }

    public static UserTransaction getUserTransaction() throws NamingException {
        UserTransaction trans = null;
        try {
            JtaTransactionManager manager = (JtaTransactionManager) SpringContextUtil.getApplicationContext()
                    .getBean("jtaTransactionManager");
            trans = manager.getUserTransaction();
        } catch (Exception e) {
            throw new NamingException(e.getMessage());
        }
        return trans;
    }
}
@Configuration
public class AtomikosConfiguration {
    @Primary
    @Bean(name = "atomDataSource")
    public AtomikosDataSourceBean businessDataSource(DataSourcePropConfig dataSourcePropConfig) {
        AtomikosDataSourceBean ds = new AtomikosDataSourceBean();
        ds.setUniqueResourceName("ds1");
        ds.setXaDataSourceClassName("oracle.jdbc.xa.client.OracleXADataSource");
        Properties properties = new Properties();
        properties.setProperty("user", dataSourcePropConfig.getUsername());
        properties.setProperty("password", dataSourcePropConfig.getPassword());
        properties.setProperty("URL", dataSourcePropConfig.getUrl());
        ds.setXaProperties(properties);
        ds.setMaxPoolSize(dataSourcePropConfig.getMaxActive());
        ds.setMinPoolSize(dataSourcePropConfig.getMinIdle());
        ds.setBorrowConnectionTimeout(dataSourcePropConfig.getMaxWait());
        ds.setMaxLifetime(dataSourcePropConfig.getMaxWait());
        String validationQuery = dataSourcePropConfig.getValidationQuery();
        if (StringUtils.isNotEmpty(validationQuery)) {
            ds.setTestQuery(validationQuery);
        }
        return ds;
    }

    @Bean(name = "jtaTransactionManager")
    public JtaTransactionManager regTransactionManager() throws Exception {
        UserTransactionManager transactionManager = new UserTransactionManager();
        transactionManager.setForceShutdown(false);
        UserTransaction userTransaction = new UserTransactionImp();
        userTransaction.setTransactionTimeout(5 * 60);
        JtaTransactionManager jta = new JtaTransactionManager(userTransaction, transactionManager);
        jta.setAllowCustomIsolationLevels(true);
        return jta;
    }
}


    

不知道你这个问题是否已经解决, 如果还没有解决的话:

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 以帮助更多的人 ^-^