【问题标题】:Spring, Hibernate, MySQL - How Transactions work - Conclusion/Questions**Spring、Hibernate、MySQL - 事务如何工作 - 结论/问题**
【发布时间】:2011-08-23 07:03:36
【问题描述】:

我使用 Spring Framework 3.0.5、Hibernate 3.6 和 MySQL Server 5.1。我有一些关于一般事务管理的问题。我个人从 spring 开始使用声明式事务管理。如果您能以是/否(或正确/不正确)回答我的问题,那将是非常棒的,如果有必要,还可以给出简短的解释。如果有不同的意见,最好有几个人回答。谢谢你:-)

1)您认为这句话是否正确:DBMS 负责事务及其行为的一般实施。

1) B) 或许最好这样说:DBMS 负责事务的一般实现和数据库的行为(例如,当事务回滚时)。

2) Hibernate 只使用数据库连接。它需要事务,但它不配置任何(!)关于事务及其行为的设置。

3) 但是:要使用事务,Hibernate 需要知道事务开始、提交和回滚的位置。

4) Hibernate 是否还需要知道发生回滚时的情况?我认为不,因为这应该在 DBMS 中定义。 (这意味着:哪些表应该被锁定,哪些数据库操作应该被撤销,等等,对吗?)

5) 对于3),可以使用编程式或声明式事务管理。

6) 在使用 programmativ 事务管理时,Hibernate 需要知道的一切 (3)) 都可以由开发人员手动写入源代码。

7) 对于声明式事务管理,需要额外的休眠框架,例如 Spring。

8) Spring 管理事务。它就像他们的框架。它触发操作,例如启动和回滚事务。

9) Spring 还可以定义哪些异常回滚必须或不能发生

10) 当回滚发生时,Spring 有什么额外的事情吗?我认为数据库负责回滚,spring只是触发它,对吧?只是为了确保......

谢谢你:-)


[编辑] 这是对 duffymo 的回答,评论太长了,我不允许在 8 小时内回答我自己的问题,这就是为什么现在我必须把它放在这里。对不起。

@duffymo

有趣的答案,这是我的想法:

  1. 所以我们同意,当事务回滚或提交时,数据库的行为(当然!)由 DBMS 直接实现或定义,对吗? 我知道事务管理器(PlatformTransactionManager),但我真的认为它只是启动事务、回滚和提交。这意味着,数据库如何处理事务是不负责任的,对吗? 我猜我的表述有误,我更新了它 (1B)

  2. 这对我来说有点抽象。这是否意味着我的句子是正确的还是不是:-)

  3. 它如何自己标记这个?我认为这必须由开发人员完成?我想到了“start tx, commit ...”,这可以由开发人员在源代码中完成

  4. 我同意。这是我在所有这些文档中发现有点难以理解的一件事。它们会告诉您哪些交易被捕获,哪些交易被捕获,但如果要找出如何处理它们,您必须自己找出来。一开始我很困惑,因为我不确定是否可以用 try/catch 块包围事务注释方法的调用,以便捕获异常并通知用户。它根本不足以让事务回滚,我需要通知用户。这就是为什么我几乎在所有地方都使用 try/catch - 你如何处理这个?

  5. 这是我不明白的一点。 Spring 提供程序化和声明式事务管理。如果 Spring 自己管理事务,当然会使用声明式 transman。程序化是……在我看来……只是程序化的。我不确定您是否可以说“Hibernate==programmatic”,因为您可以将 Hibernate 与编程和声明式事务管理一起使用。也许可以说hibernate不提供ITSELF声明式事务管理。

  6. 我什至不知道“在 JDBC”中可以做到这一点 - 我必须承认我当时不知道它是如何工作的。有点有趣的是,在阅读您的文章时,我认为我反对使用声明性事务(如果我没有误解你的话),我真的很欣赏声明性事务管理。 :-) 我认为它非常易于使用,并且在阅读代码时非常容易理解。

  7. 如果我想使用带有声明式事务管理的 Hibernate,我需要一个额外的框架,例如 Spring。因为声明性意味着,一个额外的框架“完成了你必须以编程方式完成的所有工作”。 (比如启动 tx、提交、回滚)。而且我还猜想 Spring 可能不是唯一为 hibernate 提供声明式事务管理的框架。但我的问题的要点是,如果不使用额外的框架,就不可能对休眠使用声明性事务管理。我希望我现在用正确的语言表达出来:-)

  8. 好的,正确。所以事务管理器触发回滚、启动 tx 等等

  9. 好的..

  10. 对不起 :-)

我只是想了解事物的运作方式。我一遍又一遍地阅读文档,但是如果您自己学习所有内容,那么了解基本事实很重要。这就是我问的原因:-)谢谢你的帮助! :-)

【问题讨论】:

    标签: mysql hibernate spring transactions


    【解决方案1】:

    这是我的看法:

    1. 最终提交/回滚行为是在关系数据库中完成的,但将所有责任交给数据库并不完全准确。当您同时使用 Spring、JDBC 和关系数据库时,会涉及到一个中间层,通常称为事务管理器。
    2. Hibernate 以编程方式在对象中实现事务逻辑。
    3. Hibernate 确实以编程方式标记事务的开始和结束。
    4. Hibernate 可能想知道事务是否回滚;更重要的是,您的应用需要知道这些信息才能告诉用户。
    5. 休眠 == 程序化; Spring == 声明式。
    6. 可由开发人员编写。如果您愿意,您甚至可以在 JDBC 中完成所有这些操作。但是声明性交易有充分的理由。 (你听起来像是在为不使用它们辩护。我想知道为什么?)
    7. 不明白这个 - 改写它。
    8. 事务管理器负责事务。
    9. Spring 会抛出相应的异常,是的。
    10. 您似乎一遍又一遍地重复同样的问题。

    你在这里的真正意义是什么?我很想知道。

    您始终可以在 JDBC 中以编程方式执行此操作。最终,这就是所有使用 JDBC 与关系数据库交互的 Java 解决方案所使用的,包括 Hibernate 和 Spring。这是一个模板:

    // prototypical write operation
    public void update(Connection connection) throws SQLException
    {
        connection.setAutoCommit(false);
        try
        {
            // SQL logic here
            connection.commit();  // if you get here, success
        } 
        catch (SQLException e)
        {
            try { if (connection != null) connection.rollback(); } catch (SQLException e) {}
            // might do some other things here (logging, etc.)
            // sql error codes will tell you why; spring translates these for you.
        }
        finally
        {
            // close statements here in individual try/catch blocks.
        }
    }
    

    【讨论】:

    • 感谢您的回答!请再看一下我的问题,我用一个答案更新了它!谢谢! :-)
    • 啊!现在我明白了!有趣的是,你用“in jdbc”描述的正是我一直用“编程”的意思!!!我只是说所有这些 jdbc 东西都是由开发人员在源代码中以编程方式编写的。并且通过声明它是自动将它包装在这个 jdbc 东西中的框架。
    【解决方案2】:
    1. 是的
    2. 是的
    3. 是的,你告诉 Hibernate 事务在哪里开始/结束,它告诉 DBMS
    4. 你说得对,Hibernate 不需要知道如何在 DBMS 中实现事务
    5. 是的
    6. 是的
    7. 是的
    8. 是的
    9. 是的
    10. 对,Spring 只是触发它

    从你的问题我猜你已经读过transactions in Spring docs 我建议您也阅读此IBM developerWorks article on transactions

    【讨论】:

    • 听起来不错! :-) 谢谢回答!我现在看看你的链接!
    • 我看了链接,真的很好!但我不知何故感到惊讶,因为直到现在我认为每个数据操作,甚至是带有 HIBERNATE 的只读操作都需要(!)一个事务!那么这一定是假的,因为他建议不要将事务用于只读操作。当我尝试在没有 @transactional 注释的情况下使用我的应用程序时,我总是遇到错误,即使它是用于只读操作。任何人都可以谈谈这个话题吗??
    • 在进行只读操作时,您应该始终在注释中明确声明:@Transactional(readOnly = true),这将提高性能。
    • 是的,我知道,但是 - 你读过链接了吗?作者建议不要将@transactional-annotation 用于只读操作!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-07
    • 1970-01-01
    • 2023-03-09
    • 2011-08-05
    • 1970-01-01
    • 1970-01-01
    • 2017-03-07
    相关资源
    最近更新 更多