应该将数据源的自动提交设置为false吗?

时间:2015-12-30 09:41:59

标签: java mysql oracle transactions datasource

请参阅Spring DataSourceTransactionManager.java中的注释,函数doBegin:

// Switch to manual commit if necessary. This is very expensive in some JDBC drivers,
// so we don't want to do it unnecessarily (for example if we've explicitly
// configured the connection pool to set it already).
        if (con.getAutoCommit()) {
            txObject.setMustRestoreAutoCommit(true);
            if (logger.isDebugEnabled()) {
                logger.debug("Switching JDBC Connection [" + con + "] to manual commit");
            }
            con.setAutoCommit(false);
        }

在我正在进行的项目中,未配置自动提交。所以默认情况下是这样。我们使用Spring来管理事务,所有SQL都在@Transactional注释函数中执行。因此,事务是手动提交的。每次事务开始时,db连接都将autocommit设置为false,并在事务退出后将autocommit设置回true。典型的工作流程是(在JDBC级别):

  1. conn = dataSource.getConnection();
  2. conn.setAutoCommit(假);
  3. stmt = conn.createStatement();
  4. stmt.executeQuery(...);
  5. conn.commit()/ conn.rollback();
  6. conn.setAutoCommit(真);
  7. 设置自动提交来回昂贵吗?我们应该为性能原因配置数据源连接池autocommit = false吗?跳过第2步和第6步。

3 个答案:

答案 0 :(得分:6)

1)autocommit完全依赖于数据库,这意味着,通过连接的每个语句都将在一个隐式执行的单独事务中执行。除非和直到,您希望使用个人编码并避免由多个语句持有的这些锁可能导致与其他用户冲突,否则无需将自动提交设置为false。

2)从绩效角度来看,

a)如果你有很多用户,并且由于持有数据库锁而发生了一些冲突,     那么,可能需要检查与之相关的问题,但作为一般情况     规则,自动提交是为了简化初学者的东西而引入的。

b)可能存在需要回滚的情况。

c)您希望根据特定条件手动提交交易。

编辑:我看到你编辑了这个问题,简单地回答你,autocommit = false会强迫你编写自己的commit / rollback / etc,性能完全取决于数据库,锁定的锁数量实时!!

没有。将autocommit设置为false并再次设置为true将不会增加系统的收费。

不,请不要配置数据源连接池autocommit = false,除非您出于某些特定原因并且是经验丰富的人员。从性能的角度来看,正如我已经十分认证的那样,它依赖于数据库的类型和实时用户访问实例的数据库,对于你的项目,99.99%你不需要将它设置为false。

将autocommit设置为true将确保在每个语句之后调用commit。

我也看到你从数据源获得连接,在这种情况下,最好保留连接的默认设置,以便下次从池中获取连接时,不会有任何问题与工作流程

希望这有帮助!!

答案 1 :(得分:0)

在批量操作中,您可以在会话中将其设置为关闭,并在批量操作完成后再次设置以获得性能。

SET autocommit=0;
your code here....
SET autocommit=1;

<强>更新

正如@codemania所说,即使有根据你的要求禁用自动提交的选项,但你不应该这样做。即使这是事务的基本需要,要么成功提交一组指令或回滚,如果你这样做,那么禁用你将如何实现它。

如果您正在执行数据迁移等繁琐的任务,这将非常有用,因为您可以禁用自动提交以获得性能,但仅限于该会话。

答案 2 :(得分:0)

每当您发出数据库事务时,都应将autocommit设置为true。数据库trasaction是一个逻辑工作单元,通常由多个数据库操作(通常是多个更新)组成,并且您希望所有这些操作都成功或者所有这些操作都失败。使用autocommit = false,在连接对象上调用commit()之前,您的更改将不会持久,因此这种方法可以保证所有更新都成功或失败(通过在异常情况下调用回滚等)。

当autocommit设置为true(默认值)时,您可以,例如,更改一个表,然后更改第二个更新(无论是更新/插入还是删除),可能会发生异常而您的第二个表不会不会更新,从而使您的数据库处于不一致状态。

总之,当只读数据或数据库数据模型很简单并且少数用户访问时,autocommit = true就可以了(因此对同一数据区域的并发访问非常罕见,并且当某些数据库不一致时甚至可能耐受)