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

{核心Java with Spring}通过普通JDBC调用PL SQL存储过程-理想情况下,谁应该做事务管理

慕河
2023-03-14

我的应用程序从Java/Spring调用Oracle存储过程。没有Hibernate、iBatis或Spring JDBC模板。这个服务器端/中间层是“瘦”的,没有业务逻辑检查,没有验证;它只是UI和数据库之间的数据传输层。java代码在数据检索或数据持久化时调用存储过程。存储过程是与各种表/表关系交互并聚合数据的大人物。

问题-在这种情况下,谁应该最理想地管理事务?从Java代码还是从存储过程?

通常,当中间层管理数据或执行业务逻辑或进行验证时,我们要么使用普通的JDBC/ORM框架与各种表交互,从而管理事务。但在我的用例中,SP与表交互,决定数据是正确检索还是能够持久化,为什么要依赖中间层来单独管理事务。它可以很好地知道是提交事务还是回滚事务。

总是编写一个SP,在数据检索时充当聚合函数的高级接口,在数据持久化时充当汇总函数,最后执行事务提交或事务回滚,不是更好吗?

只有在期望为特定操作调用多个SP时,中间层才需要处理事务管理。只要java代码只为特定操作调用单个存储过程[获取/更新/删除],那么在存储过程本身中管理事务提交和回滚不是很好吗?

如果SP内部出现问题,它可以回滚事务并引发异常,然后Java会将该异常消息传递给UI[或记录该消息并传递自定义异常]。

另一种想法是让SP在遇到任何异常时引发异常,然后Java代码捕获该异常并执行事务回滚。如果调用SP时没有异常,请让它执行事务提交。但是,在这里,SP已经知道了事务是成功还是失败,那么为什么我们不能自己执行提交或回滚,而是以异常或无异常的形式传递信息,让java代码执行提交/回滚呢?

更新:当事务为一个操作调用多个SP时,有一件事证明需要Java代码来管理事务是合理的。但是,同样的结果也可以通过一个高级例程来实现,该例程执行内部调用各个例程的逻辑,并最终决定提交/回滚。

请分享您对此的想法/建议/设计建议。

PS:我没有在这里共享任何代码,但这是一个编程设计问题,谁应该管理事务?

共有1个答案

柴英博
2023-03-14

这是一个哲学问题。这里没有比这更好的了,这取决于你的喜好和你的专业领域。

DBA会喜欢java程序员不会喜欢的存储过程方法。

关于事务管理,我更喜欢统一的方法评分器,而不是混合解决方案。事务管理很复杂,如果您使用SP使用数据库事务管理,我更喜欢坚持一种方法。如果您选择使用jdbc或ORM,请使用jdbc事务管理或jdbc trx管理的Spring抽象。

SP方法有其优点和缺点:

专业人士:

  1. 您可以定制特定于数据库的查询,a可能会获得优异的性能

缺点:

  1. 您依赖数据库
  2. 您的JUnit需要与数据库交互
  3. 你需要一个DBA

无论如何,我会使用spring JDBC模板,在我看来,它是一个很好的JDBC抽象,可以为您节省样板代码和bug。

如果您选择java事务管理,我将添加Spring PlatformTransactionManager。

添加spring jdbc和spring tx jar不会产生巨大的尺寸效应。这两个罐子大约是800k,我想还将添加一些额外的依赖罐子。

 类似资料:
  • 这件事困扰了我很久,所以我想在这里得到一些帮助:) 我正在使用JDBC连接到一个老旧的Sybase Adaptive server 6(!!!)我甚至在网上找不到它的JDBC驱动程序,所以我从安装目录中复制了它们:) 现在,插入和查询以及所有其余的db操作都工作得很好,但是我在调用存储过程时遇到了问题。让我们首先从一段代码开始: 提前道谢!/IVO

  • 我正在使用Spring Framework进行数据库调用。我有一个更新,涉及调用2个存储过程,每个过程都在执行多个操作。 我在每个SP中分别定义了以下事务管理: 如果我单独调用每个SP,这可以正常工作,但我想在一个事务中完成整个操作,因此如果对第一个SP的调用有效,但对第二个SP的调用失败,它会同时回滚两者。 所以很明显,我需要从sps中删除提交并在Spring端处理它。 目前对于Spring,我

  • 主要内容:创建CallableStatement对象,关闭CallableStatement对象,JDBC SQL转义语法在讨论JDBC Statement教程文章时,我们已经学习了如何在JDBC中使用存储过程。 本教程文章与该部分类似,但它将讲解演示有关JDBC SQL转义语法的其他信息。 就像对象创建和对象一样,它可使用同样的方式创建对象,该对象将用于执行对数据库存储过程的调用。 创建CallableStatement对象 假设需要执行以下Oracle存储过程 - 注意:上面的存储过程是为O

  • 我创建了一个存储过程,如下所示: //mysql中的存储过程 并且我正在调用Java中的存储过程,如下所示: //使用JDBC调用存储过程 但它显示了一个编译时异常,如下所示: CAN在参数中为存储的函数调用的返回值设置。

  • 问题内容: 我正在调用一个Sybase存储过程,该存储过程通过JDBC返回多个结果集。我需要获取一个具有名为“ Result”的列的特定结果集,这是我的代码: 这里发生的是返回很多空结果集,直到达到目标结果集为止。我不能用作循环条件,因为它对空结果集返回false。 我放置了一个固定数字以结束循环,条件是没有返回所需的结果集,以防止其进入无限循环。它工作正常,但我认为这是不对的。 我认为从Syba

  • 我希望API管理服务中的一个API调用CosmosDB中的存储过程并返回其结果。似乎没有太多关于这个主题的文件。 到目前为止我的尝试: null null null