DML statement locks table in Azure SQL Data Warehouse after implicit transaction.
See original GitHub issueDriver version
6.2.2.jre8, 6.4.0.jre8, 7.1.2.jre8-preview
SQL Server version
Microsoft Azure SQL Data Warehouse - 10.0.9999.0 Oct 10 2018 00:19:18 Copyright © Microsoft Corporation
Client Operating System
Windows 10 64 bits
JAVA/JVM version
java version “1.8.0_181” Java™ SE Runtime Environment (build 1.8.0_181-b13) Java HotSpot™ 64-Bit Server VM (build 25.181-b13, mixed mode)
Table schema
CREATE TABLE [dbo].[test_lock]
(
[id] [int] NOT NULL
)
WITH
(
DISTRIBUTION = ROUND_ROBIN,
CLUSTERED COLUMNSTORE INDEX
)
Problem description
Executing a DML statement after an implicit transaction locks the affected table. Locks are released when the connection is closed but if the connection is in a pool, it would not be closed being used.
- Expected behaviour: As long as the connection autoCommit is true, the update statement should not lock the test_lock table.
- Actual behaviour: The object Database.dbo.test_lock is locked by the update statement and the deletion cannot be executed.
- Error message/stack trace: None
- Any other details that can be helpful:
Executing the query after the lock I get the following results:
SELECT TOP ,l.[session_id] ,l.[type] ,l.[object_name] , r.[command] ,l.[acquire_time] ,r.[end_time] ,r.[status] ,l.[state] ,l.[priority] FROM [sys].[dm_pdw_lock_waits] l inner join [sys].[dm_pdw_exec_requests] r on l.request_id = r.request_id where l.[object_type] = 'OBJECT'
session_id | type | object_name | command | acquire_time | end_time | status | state | priority |
---|---|---|---|---|---|---|---|---|
SID00001 | Shared | Database.sys.sp_executesql | exec [sp_executesql] @P1 | date | date | Completed | Granted | 0 |
SID00001 | ExclusiveUpdate | Database.dbo.test_lock | UPDATE test_lock SET id = 9 WHERE id = 10 | date | date | Completed | Granted | 0 |
SID00002 | Shared | Database.sys.sp_executesql | exec [sp_executesql] @P1 | date | NULL | Running | Granted | 0 |
SID00002 | ExclusiveUpdate | Database.dbo.test_lock | DELETE FROM test_lock WHERE id > 8 | NULL | NULL | Suspended | Queued | 10 |
JDBC trace logs
Reproduction code
public class Main {
private static final String INSERT_QUERY = "INSERT INTO test_lock(id) VALUES (10)";
private static final String UPDATE_QUERY = "UPDATE test_lock SET id = 9 WHERE id = 10";
private static final String DELETE_QUERY = "DELETE FROM test_lock WHERE id > 8";
private static String driverClass = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
private static String jdbcURI = "jdbc:sqlserver://...database=Database";
private static String user = "";
private static String password = "";
public static void main(String[] args) {
try {
Class.forName(driverClass);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try (Connection c1 = DriverManager.getConnection(jdbcURI, user, password);
Connection c2 = DriverManager.getConnection(jdbcURI, user, password);) {
c1.setAutoCommit(false);
PreparedStatement ps = c1.prepareStatement(INSERT_QUERY);
ps.executeUpdate();
c1.setAutoCommit(true);
ps = c1.prepareStatement(UPDATE_QUERY);
ps.executeUpdate();
PreparedStatement ps2 = c2.prepareStatement(DELETE_QUERY);
ps2.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
Issue Analytics
- State:
- Created 5 years ago
- Comments:8 (5 by maintainers)
Top Results From Across the Web
Transaction locking and row versioning guide - SQL Server
When a connection is operating in implicit transaction mode, the instance of the SQL Server Database Engine automatically starts a new transaction after...
Read more >SQL Server lock issues when using a DDL (including SELECT ...
In this article, we will explore lock issues with DDL statements, SELECT INTO clause with Common Scenario in Deployment Utilities.
Read more >Automatic Locks in DML Operations
Table Locks (TM) A transaction automatically acquires a table lock (TM lock) when a table is modified with the following statements: INSERT ,...
Read more >"lock request time out period exceeded" Error When Trying to ...
In our case, a DML command (view redefinition) was issued againt database using SET IMPLICIT TRANSACTIONS ON without COMMIT TRANSACTION, which accidently caused ......
Read more >The best ways to use SQL DELETE Statement in a SQL table
By default, SQL Server uses implicit transactions and commits the records without asking the user. As a best practice, you should start an ......
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Hi @peterbae I’ve tested the new driver and it works perfectly. Thank you
I think that’s a good point. The problem right now is in SQLServerConnection::setAutoCommit - when setAutoCommit is called, currently we execute this command when we want to turn off implicit transaction:
This works fine for SQL Server, but for Azure DW, between the
COMMIT TRAN
andset implicit_transaction_off
statements, the server will create a new transaction since the implicit transaction was on. This is what’s causing the table to lock, and I think the driver is responsible for cleaning up that transaction.I swapped the order of those two statements (it shouldn’t affect anything other than closing the new transaction in DW), and it seems to work fine. I’ve created a Java 8 version of the newest driver that contains the change and I’ve attached it to this comment. Please give this jar a try and see if it now behaves the way you expect it to:
mssql-jdbc-7.1.3-github872.jre8-preview.jar.zip
If the jar works well for you and after further internal testing, I will create a PR that swaps the order of those two statements. Please let me know!