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

Sha*_*cer 5 java mysql oracle datasource transactions

请参阅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);
        }
Run Code Online (Sandbox Code Playgroud)

在我正在进行的项目中,未配置自动提交.所以默认情况下是这样.我们使用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(真);

设置autocommit来回昂贵吗?我们应该为性能原因配置数据源连接池autocommit = false吗?跳过第2步和第6步.

cod*_*a23 6

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

2)从性能角度来看,

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

b)在某些情况下,您需要回滚。

c)您想根据特定条件手动提交事务。

编辑:我看到您已经编辑了问题,简单地回答您,autocommit = false将迫使您编写自己的commit / rollback / etc,性能完全取决于数据库,实时持有的锁的数量!!

否,再次将autocommit设置为false和true不会增加系统的费用。

不,不要配置数据源连接池autocommit = false,除非出于某些特定原因并且经验丰富,否则不要这样做。从性能的角度来看,正如我已经介绍的那样,它取决于数据库的类型以及在某个实例中访问数据库的实时用户,对于您的项目,您不需要99.99%的将其设置为false。

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

我还看到您正在从数据源获取连接,在这种情况下,最好将连接保留为默认设置,以便下次从池中获取连接时,工作流程不会有任何麻烦

希望这有所帮助!


Zaf*_*lik 0

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

SET autocommit=0;
your code here....
SET autocommit=1;
Run Code Online (Sandbox Code Playgroud)

更新:

正如 @codemania 很好地解释的那样,即使可以选择根据您的要求禁用自动提交,但您不应该这样做。即使这是成功提交一组指令或回滚的事务的基本需求,如果您禁用它,那么您将如何实现它。

如果您正在执行一些繁重的任务(例如数据迁移等),这将很有用,因为您可以禁用自动提交来获得性能,但只能在该会话中进行。