Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么要将自动提交设置为true?_Java_Jdbc - Fatal编程技术网

Java 为什么要将自动提交设置为true?

Java 为什么要将自动提交设置为true?,java,jdbc,Java,Jdbc,很长一段时间以来,我一直想知道为什么JDBCAPI提供了自动提交模式(java.sql.Connection.setAutocommit())。这似乎是一个吸引人的讨厌的东西,只会把人们引向麻烦。我的理论是,它被添加到JDBC中只是为了简化那些希望使用JDBC创建编辑和运行SQL工具的供应商的工作。打开自动提交还有其他原因吗?还是总是错误?提交模式会改变数据库持有锁的方式 建议仅在事务模式期间禁用自动提交模式。通过这种方式,您可以避免为多个语句持有数据库锁,这会增加与其他用户发生冲突的可能性

很长一段时间以来,我一直想知道为什么JDBCAPI提供了自动提交模式(
java.sql.Connection.setAutocommit()
)。这似乎是一个吸引人的讨厌的东西,只会把人们引向麻烦。我的理论是,它被添加到JDBC中只是为了简化那些希望使用JDBC创建编辑和运行SQL工具的供应商的工作。打开自动提交还有其他原因吗?还是总是错误?

提交模式会改变数据库持有锁的方式

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

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


我能看到的唯一合理原因是,在小型应用程序中,在简单的单查询事务中,去掉
连接.commit()
连接.rollback()
样板文件。原始形式的JDBC本身就需要大量的样板文件。每少一行都会让JDBC对初学者不那么可怕。

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

对于MySQL,您可以在默认情况下保持autocommit=true处于打开状态,当您开始事务时,它会自动关闭该选项。设置autocommit=false的唯一原因是,如果有人试图在没有开始的情况下启动事务,您希望强制执行错误

为了简化目前典型的Java+MySQL应用程序,我或多或少会忽略自动提交设置,使用视图模式中的开放会话并称之为良好


我强烈反对显式RDBMS行锁,而是使用乐观锁。Hibernate提供了对乐观锁的内置支持,但它是一种很容易采用的模式,即使是手工编写的代码,也能提供更好的性能。

95%我现在使用的代码库都涉及到单次更新,其中启用自动提交是完全合理的。因此,我们默认将其启用。只需将其关闭足够长的时间,以执行需要成为事务的代码部分,自动提交就会重新启动

我几乎总是使用autocommit=true运行。99%的时候,我的更新是原子的。当然,在有些情况下,如果你写了借方,但写了贷方却失败了,那么你就要回滚。但以我的经验来看,这是相对罕见的。通常我写的每一张唱片都是独立的。在这种情况下,无需在每次写入后进行提交就很方便了。它在这里和那里保存一行代码。如果给定程序的结构,这意味着我不需要额外的try/catch块,或者我不需要在函数之间传递连接对象,那么它可能会节省更多。它节省了一些令人讨厌的错误,比如有人忘了做提交

我认为这可能“诱使某人陷入麻烦”的唯一方式是,他认为关闭自动提交并执行提交或回滚操作太麻烦了,因此他会单独在事务中进行更新。然后,只要没有发生任何应该中止事务的事情,一切都会正常工作。如果测试场景不充分,我可以想象这将滑入生产

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


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

自动提交方便;但是随着对JDBC3规范的修改,它变得不再那么有用了

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

因此,在SELECT中循环并发布更新(甚至嵌套SELECT)往往会失败。显然,这是一种犯罪,实际上想做一些事情的结果,你的外部选择


无论如何,这取决于特定的驱动程序和版本。。但总体而言,JDBC3规范似乎规定了这种无益的行为。升级驱动程序也会毫无帮助地“发现”这种行为

为什么要使用自动提交?最初,它是有帮助和方便的。正如其他答案所说,JDBC需要大量的废话和处理才能正确调用。。JDBC并不是一个设计良好的API:(


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

例如,在ServletRequest开始时绑定您的连接/事务;并在结束时返回它


您可以使用javax.servlet.Filter或类似工具,并将其绑定到本地线程,使静态助手获取或需要它,等等。

在glo启用“自动提交”时,需要仔细查看某些条件