Question

I've written a procedure to dump table data out to a text file like so (assume the relevant variables have been declared);

SET @sql = '"SELECT * FROM ##OutputData"'

SET @cmdline = 'bcp '+ @sql +' queryout '+@OutputPath+'\outputFile.csv -c -t -T -S' + @@ServerName

EXEC master..xp_cmdshell @cmdline

This procedure works fine when executed from inside SQL Server, but not when it is called from JDBC in Java.

By looking at the activity monitor I can see that a transaction operating the query "SELECT * FROM ##OutputData" is being blocked by the transaction that is performing the procedure. Effectively deadlocking the process.

I have played around with the code and can't see why this would happen at all. Is there something that I'm missing somewhere?

Thanks for any help...

EDIT: Changed references to Quartz to JDBC instead because that's probably more relevant.

Was it helpful?

Solution

I believe I have found the answer to this issue.

Since Spring uses it's own transaction manager, it is locking the tables that I am creating in the procedure. When that procedure executes BCP, it runs in SQL Server, outside the scope of the Spring transaction. Therefore BCP cannot access the tables it needs to because they are locked by Springs transaction. The procedure cannot continue because it is waiting on BCP so the whole process hits deadlock.

I have noticed that this occurs wherever a BCP command has an outer transaction, and although BCP has a TransactionIsolation Flag, this doesn't seem to have any effect in this instance.

To resolve the issue I am now using SQL Server Jobs to run the procedure, with no transactions.

Anyway, at least I can be grateful that this question earned me the 'Tumbleweed' badge ;) Thanks all!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top