为什么将Autocommit设置为true?

Nat*_*hes 30 java jdbc

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

Bal*_*usC 18

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


Wil*_*son 13

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

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

为了简化当今典型的Java + MySQL应用程序,我或多或少会忽略自动提交设置,使用open-session-in-view模式并将其称为好.

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

  • 澄清典型的Java + MySQL应用程序:将auto-commit设置为true.在传入请求(网页或REST/JSON)的开头打开一个会话(并开始一个事务).如果请求正常处理,请在请求处理结束时提交事务.然后,将回滚添加回请求的500页呈现.这基本上就是Play Framework处理事物的方式.它对用户和开发人员来说都很直观. (2认同)

Jay*_*Jay 9

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

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

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

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


Tho*_*s W 7

自动提交很方便; 但随着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或类似的,并将其绑定到线程本地,创建一个静态帮助器来获取它或需要它,等等.


nat*_*e c 5

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

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

...

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

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

  • 当然,我只是认为教程的​​实际情况是"你应该使用自动提交来防止数据库锁争用".是不诚实的.这是一个过于简单的一揽子索赔,在2010年可能已成为少数用例.(但作为对所提出的实际问题的回答,确实能够很好地了解为什么(老化)API的设计方式!) (2认同)