自动提交打开时“设置事务”是不是启动事务?

Posted

技术标签:

【中文标题】自动提交打开时“设置事务”是不是启动事务?【英文标题】:Does "set transaction" start a transaction when autocommit is ON?自动提交打开时“设置事务”是否启动事务? 【发布时间】:2015-12-10 20:14:27 【问题描述】:

我正在使用具有 AutoCommit ON 模式的 Oracle(使用 JDBC 的 Java 应用程序)。

当我将多个 DML 语句作为单个事务执行时,我想我可以这样做:

set transaction read write
update user_tbl set name='mark' where email='m@xyz.com'
update user_tbl set name='ken' where email='k@xyz.com'
--if other things are successful, then:
commit
-- else:
--rollback

但是看起来,每当我最终执行rollback 时,这些行都具有我上述语句给出的新值。

那么,即使set transaction 是在开始时执行的,update 语句是否有可能在 AutoCommit ON 模式下执行?

【问题讨论】:

【参考方案1】:

这在文档中有清楚的解释: http://docs.oracle.com/javase/7/docs/api/java/sql/Connection.html http://docs.oracle.com/javase/7/docs/api/java/sql/Connection.html#setAutoCommit(boolean)

注意:配置 Connection 时,JDBC 应用程序应使用适当的 Connection 方法,例如 setAutoCommit 或 setTransactionIsolation。 当有 JDBC 方法可用时,应用程序不应直接调用 SQL 命令来更改连接的配置。 默认情况下,Connection 对象处于自动提交模式,这意味着它会在执行每条语句后自动提交更改.如果自动提交模式已被禁用,则必须显式调用 commit 方法以提交更改;否则,数据库更改将不会被保存。


setAutoCommitvoid setAutoCommit(boolean autoCommit) 抛出 SQLException 将此连接的自动提交模式设置为给定状态。 如果连接处于自动提交模式,则其所有 SQL 语句将作为单独的事务执行和提交。 否则,其 SQL 语句将分组为通过调用任一方法终止的事务提交或方法回滚。默认情况下,新连接处于自动提交模式。 语句完成时发生提交。语句完成的时间取决于 SQL 语句的类型:

对于 DML 语句(例如 Insert、Update 或 Delete)以及 DDL 语句,语句在执行完毕后即告完成。 对于 Select 语句,当关联的结果集关闭时,该语句就完成了。 对于 CallableStatement 对象或返回多个结果的语句,当所有关联的结果集都已关闭并且已检索所有更新计数和输出参数时,该语句就完成了。 注意:如果在事务期间调用此方法并且更改了自动提交模式,则提交事务。如果调用了 setAutoCommit 并且自动提交模式没有改变,则调用是空操作。


上面的意思是,你的代码在自动提交模式下运行,相当于:

set transaction read write;
commit; -- invoked by JDBC autocommit
update user_tbl set name='mark' where email='m@xyz.com';
commit; -- invoked by JDBC autocommit
update user_tbl set name='ken' where email='k@xyz.com';
commit; -- invoked by JDBC autocommit
--if other things are successful, then:
commit;
commit; -- invoked by JDBC autocommit

【讨论】:

以上是关于自动提交打开时“设置事务”是不是启动事务?的主要内容,如果未能解决你的问题,请参考以下文章

mysql数据库中我把表中没用的字段删了,下次我打开时又自动出现了,再删还是会出现,是怎么回事?

Mysql数据库系列数据表事务锁处理

mysql 中手动设置事务提交

JDBC——事物管理

MySQL事务

Java 事务