如果我设置连接到手动提交是否意味着我的进程将锁定数据库?如果我必须执行可能需要4-5个小时才能执行的多个SQL查询,这是否意味着在此期间没有其他用户可以访问我的数据库?
我正在采用Web应用程序的场景,其中有成千上万的用户访问同一个数据库。
connection.setAutoCommit(false);
//multiple sql query that will probably take 4-5 hours to be executed
connection.commit();
答案 0 :(得分:7)
将autocommit设置为false通常对读取没有影响,因此,如果这是您正在运行的查询类型,则不应该成为问题。
autocommit = false保证是您在事务中执行查询(插入,删除,更新),这意味着它们都会成功(最后提交) ,或者失败,然后回滚。
当您插入,更新或执行select ... for update
时,某些行将被锁定,这很难预测,因为它取决于您的引擎,Mysql版本,隔离级别等。
例如,如果autocommit = false并且两个用户需要同时更新相同的行,那么一个将锁定,等待第一个完成,提交或回滚。
让我们说 USER1 会触发数据库的更新,目标是10行。
您开始交易,进行更新,再做几次查询......
在提交/回滚之前, USER2 会触发相同的更新,或者针对 USER1 正在更新的一个或多个相同行的更新。
USER2 将被锁定,等待 USER1 提交或回滚,然后才能执行更新。
测试此方法的一种方法是打开与数据库的两个不同连接,例如,通过命令行或其他一些客户端,并模拟此行为。 将autocommit设置为false,在一个客户端上执行更新,在第二个客户端上执行相同操作,并看到它挂起,直到您在第一个客户端上提交或回滚。
这项技术可以非常方便地帮助您了解幕后发生的事情。
答案 1 :(得分:6)
connection.setAutoCommit(假);表示您正在此连接上启动事务。您将对此连接中的数据库表所做的所有更改将在提交时保存,或在还原时还原(或在不提交时断开连接)。这并不意味着您锁定整个数据库。是否锁定其他用户试图访问您的事务所使用的表将取决于您的事务正在执行的操作和事务隔离级别。
答案 2 :(得分:0)
这取决于隔离级别以及您正在做的事情:
如果您正在阅读:
如果您正在进行更新,其他任务将受到影响。一般来说,您不应该在长时间运行的事务中进行更新。