为什么将Autocommit设置为true?

我很想知道为什么JDBC API提供自动提交模式( java.sql.Connection.setAutocommit() )。 这似乎是一种吸引人的麻烦,只会引诱人们陷入困境。 我的理论是它只是添加到JDBC中,以简化那些希望创建使用JDBC编辑和运行SQL的工具的供应商的生活。 有没有其他理由打开自动提交,或者它总是一个错误?

不幸的是,使用自动提交是特定于数据库的(就像事务行为一样)。 我认为如果你没有全局的,程序化的事务策略,autocommit可能比希望每个人都正确关闭/回滚事务更好。

说到MySQL,你可以默认启用autocommit = true,当你开始交易时它会自动关闭它。 设置autocommit = false的唯一原因是,如果有人尝试在没有BEGIN的情况下尝试启动事务,则强制发生错误。

为了简化当今典型的Java + MySQL应用程序,我或多或少会忽略自动提交设置,使用开放式会话视图模式并将其称为好。

我强烈反对显式的RDBMS行锁,而是使用乐观锁。 Hibernate提供对乐观锁的内置支持,但即使对于手动代码也是一种简单的模式,并提供更好的性能。

我能看到的唯一合理的原因是在小应用程序中的简单单查询事务中摆脱connection.commit()connection.rollback()样板。 原始forms的JDBC本身已经需要很多样板。 每一行都会让JDBC对初学者不那么可怕。

我几乎总是使用autocommit = true运行。 99%的时间,我的更新是primefaces的。 当然,有些情况下,如果您编写借记,然后尝试写入您想要回滚的信用失败。 但根据我的经验,这些是相对罕见的。 通常我写的每条记录都是独立的。 在这种情况下,在每次写入之后不需要费心去做提交很方便。 它在这里和那里保存了一行代码。 如果给定程序的结构,它意味着我不需要额外的try / catch块或者我不需要在函数之间传递连接对象,它可以节省更多。 它节省了有人忘记做提交的烦人的错误。

我认为它可以“引诱某人陷入困境”的唯一方法是他决定关闭自动提交并执行提交或回滚是非常麻烦的,所以他做的更新应该在一个事务中单独进行。 然后,只要没有任何事情应该中止事务,所有事情都可以正常工作。 如果测试场景不合适,我可以想象这会滑入生产阶段。

但你几乎可以对语言的任何特征说同样的话。 比如,假设你编写了一个处理数字的程序,这个程序90%的时间都适合很长时间,但偶尔可能会更大。 面对这种情况,正确的做法是使用BigInteger或创建一个新类来处理更大的数字。 一个懒惰的程序员可能会被诱骗使用很长时间,因为它通常会起作用,而其他替代方案则太麻烦了。 您是否因此得出结论认为Java不应该包含long(或int),因为有人可能会在不适合时使用它们?

如果在您的程序中,大多数更新必须在事务上下文中完成,则关闭自动提交。 它的存在并没有伤害到你。 这是方便的时候,但是当它不是你可以把它关掉。

自动提交很方便; 但随着JDBC 3规范的改变,已经变得不那么有用了。

由于“自动提交”模式下的JDBC 3连接不能打开多个Statement。 执行另一个语句将关闭第一个 – 包括任何ResultSet。

因此,在SELECT中循环并发出UPDATE(甚至嵌套的SELECT)将倾向于失败。 显然这是一种犯罪,实际上想要对外部SELECT的结果做些什么


无论如何,取决于具体的驱动程序和版本..但一般来说,JDBC 3规范似乎要求这种无益的行为。 升级驱动程序也可能无助于“发现”此行为。

为什么要使用自动提交? 最初,它很有帮助和方便。 正如其他答案所说,JDBC需要大量的GUFF和HANDLING来正确调用.. JDBC并不是一个设计良好的API 🙁


现在,您最好使用Hibernate或Spring的JdbcTemplate ..如果您正在使用servlet / Web应用程序,请在边界处放置事务管理(开始/结束)或Hibernate会话(将其绑定到线程本地) “用户请求”。

例如,在ServletRequest开始时绑定你的连接/事务; 并在最后归还。

您可以使用javax.servlet.Filter或类似的,并将其绑定到线程本地,创建一个静态帮助器来获取它或需要它,等等。

提交模式更改数据库保持锁定的方式。

建议仅在事务模式期间禁用自动提交模式。 这样,您可以避免为多个语句保留数据库锁,这会增加与其他用户冲突的可能性。

为了避免事务期间的冲突,DBMS使用锁定机制来阻止其他人访问事务正在访问的数据。 (请注意,在自动提交模式下,每个语句都是一个事务,只保留一个语句的锁。)

http://download.oracle.com/javase/tutorial/jdbc/basics/transactions.html

我现在使用的95%的代码库都涉及单个更新,其中自动提交是完全合理的。 所以,我们默认它。 只需将其关闭足够长的时间来完成需要成为事务的代码段,然后自动提交就会重新开启!

那么在某些条件下需要仔细查看,同时在全局级别启用“自动提交”:

a。)查询级别的事务管理将留给用户,对于一个实例,如果需要一堆查询成功或一起失败,那么它需要被包装在BEGIN和提交事务之下。

b。)请记住,启用“自动提交”时没有回滚。

c。)每次交易都有写入(提交)的开销。

d。)对于只读查询,没有明确需要“自动提交”,但通过启用“自动提交”,它会自动对所有查询强制执行。

如果表锁定是启用自动提交的唯一问题,那么它可能不是一个好主意,而是可以采用较低的锁定超时。