简体   繁体   English

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

[英]Should autocommit of a datasource be set to false?

please see the comments in spring DataSourceTransactionManager.java, function doBegin: 请参阅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);
        }

In the project I'm working on, autocommit is not configured. 在我正在进行的项目中,未配置自动提交。 So it is true by default. 所以默认情况下是这样。 We are using Spring to manage transactions, and all SQLs are executed within @Transactional annotated functions. 我们使用Spring来管理事务,所有SQL都在@Transactional注释函数中执行。 So Transactions are acturally manually committed. 因此,事务是手动提交的。 Everytime a transaction begin, the db connection is set autocommit to false, and after the transaction exit autocommit is set back to true. 每次事务开始时,db连接都将autocommit设置为false,并在事务退出后将autocommit设置回true。 A typical workflow would be (at JDBC level): 典型的工作流程是(在JDBC级别):

  1. conn = dataSource.getConnection(); conn = dataSource.getConnection();
  2. conn.setAutoCommit(false); conn.setAutoCommit(假);
  3. stmt = conn.createStatement(); stmt = conn.createStatement();
  4. stmt.executeQuery(...); stmt.executeQuery(...);
  5. conn.commit()/ conn.rollback(); conn.commit()/ conn.rollback();
  6. conn.setAutoCommit(true); conn.setAutoCommit(真);

Is setting autocommit back and forth expensive? 设置autocommit来回昂贵吗? should we config datasource connection pool autocommit=false for performance reason? 我们应该为性能原因配置数据源连接池autocommit = false吗? to skip the step 2 and step 6. 跳过第2步和第6步。

1) autocommit is totally dependent on the database, what it means is that, each and every statement through the connection will be executed in a separate transaction which is implicitly carried out. 1)autocommit完全依赖于数据库,这意味着,通过连接的每个语句都将在一个隐含执行的单独事务中执行。 Unless and until, you want to use personal coding and avoid those locks being held by multiple statements which could lead to conflicts with other users, there is no need to set the autocommit to false. 除非和直到,您希望使用个人编码并避免由多个语句持有的这些锁可能导致与其他用户冲突,因此无需将自动提交设置为false。

2)From performance points of view, 2)从绩效的角度来看,

a) if you have a lot of users and there is some conflict that is occuring because of holding of database locks, then, there may be a need to check into the issues pertaining to it but as a general rule, autocommit was introduced for simplification of stuff for beginners. a)如果你有很多用户并且由于持有数据库锁而发生了一些冲突,那么可能需要检查与之相关的问题,但作为一般规则,引入了自动提交以简化初学者的东西。

b) there may be instances where you need to rollback . b)可能存在需要回滚的情况。

c) you want to commit the transaction manually based on a specific condition. c)您希望根据特定条件手动提交事务。

EDIT: I see you have edited the question, to answer you simply, autocommit=false will force you to write your own commit/rollback/etc, performance is totally dependent on the database, the number of locks held at a moment in real time!! 编辑:我看到你编辑了这个问题,简单回答你,autocommit = false会强迫你编写自己的提交/回滚/等,性能完全取决于数据库,实时锁定的数量!

No. setting autocommit to false and true again will not increase the toll on the system. 编号将autocommit设置为false并再次为true将不会增加系统的收费。

NO, do not config datasource connection pool autocommit=false unless you are doing it for some specific reason and are an experienced person. 不,不要配置数据源连接池autocommit = false,除非您出于某些特定原因并且是经验丰富的人员。 From performance points of view, as i already decalred, it is dependent on the type of database and real time users accessing the database at an instance, for your project, 99.99 percent you wouldn't be needing to set it to false. 从性能的角度来看,正如我已经十分认证的那样,它依赖于数据库的类型和实时用户访问实例的数据库,对于您的项目,99.99%的百分比您不需要将其设置为false。

setting autocommit to true will just ensure that commit is called after each and every statement. 将autocommit设置为true只会确保在每个语句之后调用commit。

I also see that you are getting your connection from a datasource, in such cases, it is best to leave the connection with default settings so that the next time that connection is fetched from the pool, there wouldn't be any trouble with the workflow 我还看到你从数据源获得连接,在这种情况下,最好保留连接的默认设置,以便下次从池中获取连接时,工作流程不会有任何问题

Hope this helped!! 希望这有帮助!!

In bulk operations you can set it off in your session and set again on after bulk operation completion to gain performance. 在批量操作中,您可以在会话中将其设置为关闭,并在批量操作完成后再次设置以获得性能。

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

Update: 更新:

As @codemania explained very well that even there is option to disable autocommit as per your requirement but you should not do this. 正如@codemania非常清楚地解释说,即使有根据您的要求禁用自动提交的选项,但您不应该这样做。 Even this is basic need of transaction to either successfully commit a set of instructions or rollback, if you do it disable then how you will achieve it. 即使这是事务的基本需要,要么成功提交一组指令或回滚,如果你这样做,那么禁用它将如何实现它。

This will be useful if you are doing some bulky task like data migration etc, for it you can disable autocommit to gain performance but only in that session. 如果您正在执行一些繁琐的任务(如数据迁移等),这将非常有用,因为您可以禁用自动提交以获得性能,但仅限于该会话。

You should set autocommit to true whenever you're issuing database transactions. 每当发出数据库事务时,都应将autocommit设置为true。 A database trasaction is a logical unit of work, which usually consists of multiple database operations (usually multiple updates) and you want either all of them to succeed or all of them to fail. 数据库trasaction是一个逻辑工作单元,通常由多个数据库操作(通常是多个更新)组成,并且您希望所有这些操作都成功或者所有这些操作都失败。 With autocommit=false, your changes will not be made persistant until you call commit() on the connection object, so this approach guarantees that all your updates will either succeed or fail (by calling rollback in case of an exception etc). 使用autocommit = false,在连接对象上调用commit()之前,您的更改将不会持久,因此这种方法可以保证所有更新都成功或失败(通过在异常情况下调用回滚等)。

When autocommit is set to true (the default), you can, for instance, change one table but then on the second update (whether it be an update/insert or delete), an exception may occur and your second table doesn't get updated, thus leaving your database in an inconsistent state. 当autocommit设置为true(默认值)时,您可以,例如,更改一个表,然后更改第二个更新(无论是更新/插入还是删除),可能会发生异常而您的第二个表无法获取更新,从而使您的数据库处于不一致状态。

In conclusion, autocommit=true is OK when just reading data or when the database data model is simple and accessed by few users (so that concurrent access to the same regions of data is very rare and when some database inconsistencies can even be tolerated) 总之,当只读数据或数据库数据模型很简单并且少数用户访问时,autocommit = true就可以了(因此,对同一数据区域的并发访问非常罕见,甚至可以容忍某些数据库不一致)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM