当前位置: 首页 > 知识库问答 >
问题:

MyBatis没有Spring,事务使用提供的连接

袁赞
2023-03-14

我使用的是没有Spring的MyBatis。我还必须使用另一个API提供的JDBC连接。

所以我创建了我的SqlSession,如下所示:

    Connection conn = //... provided by some API
    LOGGER.debug("Connection autocommit: " + conn.getAutoCommit()); // Autocommit is true by default
    conn.setAutoCommit(false); // So I set it to false first
    LOGGER.debug("Connection autocommit after: " + conn.getAutoCommit()); // It is now false
    return factory.openSession(conn);

然后在我的代码中:

    try (SqlSession session = ...) {
        // Invoke mapper method here
        session.commit();
    } catch (Exception ex) {
        session.rollback();
        throw ex;
    }

然而,我发现调用session.commit()什么也不做(即没有找到关于提交的日志),并且更改确实没有提交。似乎MyBatis的提交()由于某种原因被忽略了。

如果我不强制autocommit为false,更改将被提交(无需调用session.commit()),但我也无法回滚错误。

我的SqlSessionFactory是这样创建的:

configuration = new Configuration();
configuration.setDatabaseId(SQLSERVER_DATABASE_ID);                 
configuration.addMapper(ApprovalHierarchyMapper.class);     
factory = new SqlSessionFactoryBuilder().build(configuration);

如何在没有Spring和提供的JDBC连接的情况下实现以编程方式控制的事务?

共有2个答案

艾翼
2023-03-14

我刚刚测试并session.commit()按预期工作。

SqlSessionFactory创建如下。

Environment env = new Environment("development",
  new JdbcTransactionFactory(), new UnpooledDataSource());
Configuration config = new Configuration(env);
config.addMapper(YourMapper.class);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(config);
  • 使用JdbcTransactionFactory代替默认的ManagedTransactionFactory
  • UnpooledDataSource将不被使用。

调用映射器方法的部分看起来与您的示例相同。

con.setAutoCommit(false);
try (SqlSession session = sqlSessionFactory.openSession(con)) {
  YourMapper mapper = session.getMapper(YourMapper.class);
  // Invoke mapper methods here
  session.commit();
}

事务在引发异常时回滚。

慕容康安
2023-03-14

我认为这是因为我没有为SqlSessionFactory的协构造函数提供环境,导致了这种奇怪的情况。环境包含对TransactionManager的引用。

因此,我尝试添加Apache Commons池和DBCP,并使用虚拟BasicDataSource和JdbcTransactionManager构建环境。然而,我发现代码将真正尝试连接到BasicDataSource,我没有有效的URL/login/password,因为我是从API获得连接的。

然后我试着给session打电话。获取连接。提交()/回滚(),而不是会话。提交()/回滚()。这奏效了。

这是由我以编程方式构造配置引起的,我必须这样做,因为我的程序是软件的插件,一些数据只有在我访问插件上下文时才能在运行时访问。

 类似资料:
  • 当somehelper类中的任何方法(将传播行为设置为“requires_new”的事务块)中出现某些异常时,为什么调用方类中不处理它(具有默认传播行为的事务块)?我看到的不是消息“catch inside doOperationMetadata of Impl class”,而是消息“catch inside callServiceMethod of Controller class”。

  • 是否可以使用https协议在tomcat上部署apache cxf rs?我看到很多使用嵌入式jetty的例子,但我不想要它。 我应该在这里补充更多细节,我不知道具体怎么做。我有以下配置:在网络上。xml 在cxf-config.xml: 在服务器中也是如此。xml端口8443上启用了SSL,但我得到了一个例外:java。伊奥。IOException:端口8443的协议不匹配:引擎的协议是http

  • 问题内容: 当我有嵌套在根组件下的组件时,我无法实例化我的应用程序,该组件在其构造函数中使用。 我想知道为什么这种行为是非法的。假设我想在班级中使用该类,而只是在班级中引用该类。这似乎是不可能的。 创建层次结构的正确方法是什么? 谢谢你 PLNKR:http ://plnkr.co/edit/5Z0QMAEyZNUAotZ6r7Yi?p=preview 问题答案: 您可以直接将父组件注入到组件中,

  • 问题内容: 我只是熟悉Apache JackRabbit。我已经完成了一些用于文档管理的多用户存储库。 如果有人同时使用它们,您能回答这些问题吗? ModeShape是否以某种方式链接到JBoss?我对JBoss AS或任何其他JBoss工具没有太多经验。我看到了对tomcat的支持,但是有很多JBossy的东西 文档说将来的发行版应该具有UI集成,这还有很长的路要走吗?它将是什么样的UI集成?是