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;
}
}