cancel
Showing results for 
Search instead for 
Did you mean: 

Deadlock after changing connection from Biztalk and ODBC to DELL Boomi and JDBC

fvestjens
Participant
0 Kudos
2,712

A customer has switched the communication to a SQL Anywhere database from ODBC and BizTalk to Dell Boomi and a jdbc connector. When they are adding records to the database through the DELL BOomi interface they get deadlocks.

The Dell Boomi interface is written in Java and is using sqljdbc42.jar. The settings for the jdbc driver are:

User : test 
Class Name : com.sybase.jdbc3.jdbc.SybDriver
Connection URL : jdbc:sybase:Tds:DECSYB01:2638/testDCFusion

The other properties that can be set can be found here:
link:(http://help.boomi.com/atomsphere/GUID-56BCB840-4F3E-49FB-8DBA-1B8EDA3BB399.html "Boomi Connector properties")

It looks like the threads are waiting for each other as I can see from the deadlock loggin in the database.

snapshotId,snapshotAt,waiter,who,what,wait_on,owner
1,'2018-08-21 08:12:29',83703,'test',,38659038169,83701
1,'2018-08-21 08:12:29',83701,'test',,4297369914,83703
2,'2018-08-21 08:18:31',83732,'test',,42954005469,83731
2,'2018-08-21 08:18:31',83731,'test',,2402624,83732
3,'2018-08-21 08:18:32',83730,'test',,42954005469,83732
3,'2018-08-21 08:18:32',83732,'test',,2402625,83730
4,'2018-08-21 08:18:32',83734,'test',,42954005469,83733
4,'2018-08-21 08:18:32',83733,'test',,4297369921,83734

Is there anyone having an idea what needs to be changed in the connection properties to solve it or is there a setting on the database that I need to change.

The database is running on SQL Anywhere 9.0 (I know it's very old but still does the job)

TIA

Frank

Accepted Solutions (0)

Answers (2)

Answers (2)

fvestjens
Participant

What is the correct way to set the isolation level on the client when using the following:

jdbc:sybase:Tds:DECSYBT0:2638/DCFUSIONDR

We tried jdbc:sybase:Tds:DECSYBT0:2638/DCFUSIONDR;isolation_level=0 but that still shows level 1 in the connection.

Is there any documentation on this? Is there a default way to do this?

Breck_Carter
Participant

It doesn't matter what you set the database-level isolation level to, if every time a connection starts it is sent through the nightmare called sp_tsql_environment which changes the connection-level isolation level by executing SET TEMPORARY OPTION isolation_level='1';

One solution is to add code to change the connection-level isolation level after login.

Or (much better)... you could take control by coding your own login_procedure that does NOT call sp_tsql_environment.

Here is the full story...

The default login_procedure option is this: SET OPTION PUBLIC.login_procedure = 'sp_login_environment';

That forces all your connections to call this, which in turn sends TDS (i.e., jConnect and Open Client) connections to sp_tsql_environment:

ALTER PROCEDURE "dbo"."sp_login_environment"()
begin
  if "connection_property"('CommProtocol') = 'TDS' then
    call "dbo"."sp_tsql_environment"()
  end if
end

This truly evil procedure tries to make SQL Anywhere behave like a Sybase SQL Server database from 1995:

ALTER PROCEDURE "dbo"."sp_tsql_environment"()
begin
  if "db_property"('IQStore') = 'Off' then
    -- SQL Anywhere datastore
    set temporary option "close_on_endtrans" = 'OFF'
  end if;
  set temporary option "ansinull" = 'OFF';
  set temporary option "tsql_variables" = 'ON';
  set temporary option "ansi_blanks" = 'ON';
  set temporary option "chained" = 'OFF';
  set temporary option "quoted_identifier" = 'OFF';
  set temporary option "allow_nulls_by_default" = 'OFF';
  set temporary option "on_tsql_error" = 'CONTINUE';
  set temporary option "isolation_level" = '1';
  set temporary option "date_format" = 'YYYY-MM-DD';
  set temporary option "timestamp_format" = 'YYYY-MM-DD HH:NN:SS.SSS';
  set temporary option "time_format" = 'HH:NN:SS.SSS';
  set temporary option "date_order" = 'MDY';
  set temporary option "escape_character" = 'OFF'
end

If you NEVER want that to happen, try this:

SET OPTION PUBLIC.LOGIN_PROCEDURE = '';

Or substitute your own code:

CREATE PROCEDURE DBA.my_login_procedure()
BEGIN
  -- do whatever you want
END;

SET OPTION PUBLIC.LOGIN_PROCEDURE = 'DBA.my_login_procedure';
Breck_Carter
Participant

Be sure to let us know if changing the isolation level to 0 stops the deadlocks.

VolkerBarth
Contributor

As stated above, you could also try to use a table hint within the query that tries to read freshly inserted rows... If only one or a few tables are involved, that may be easier than altering the login procedure...

Breck_Carter
Participant

> easier than altering the login procedure

Easier than one line of code, executed once?

SET OPTION PUBLIC.LOGIN_PROCEDURE = '';

That restores the behavior from before jConnect was introduced.

VolkerBarth
Contributor

Well, possibly "easier" in the sense of "with less side effects", because the login procedure does influence those many options... Apparently, I can't tell whether those options are fitting or not..

Breck_Carter
Participant

Well, you can take a guess... do you think Dell Boomi needs autocommit (chained off)?

No, neither do I ... NOBODY needs chained off 🙂

Chained off is a relic from Sybase SQL Server 4.2.

I guess my REAL point here is that anyone who suddenly gets sp_tsql_environment shoved up their nose, SHOULD examine the changed settings with a GREAT CARE, if they care about the correct operation of their application. Patching the isolation level isn't enough.

VolkerBarth
Contributor

Well, I certainly agree on the REAL point, particularly when the previous client stack has not used the TDS protocol.

fvestjens
Participant
0 Kudos

When I make the change for the login_procedure to be blank. It will be removed from the database option list. Which is fine for us.

However the application using the JDBC connection then gets an error message 'ASA -143: Column '@p0' not found'

Even if I add my own login procedure we get the same error. My login procedure is blank.

We're running on build 2451.

Breck_Carter
Participant

This may be a brand new, completely different, symptom... not directly related to the deadlocks or login procedure.

The following queries look inside all the SQL code stored inside the database for the substring @p0

BEGIN
SELECT * FROM SYSTABLE     WHERE view_def     LIKE '%@p0%';
SELECT * FROM SYSPROCEDURE WHERE proc_defn    LIKE '%@p0%';
SELECT * FROM SYSTRIGGER   WHERE trigger_defn LIKE '%@p0%';
SELECT * FROM SYSEVENT     WHERE source       LIKE '%@p0%';
END;
Breck_Carter
Participant

The name @p0 most likely appears in user-written code somewhere.

You can trace the queries coming from client applications by using the "request logging" feature.

See dbsrv9 -zr and -zo in the Help.

You can also do this...

call sa_server_option ( 'RequestLogFile', 'C:\\\\temp\\\\whatever.txt' );
call sa_server_option ( 'RequestLogging', 'SQL+hostvars' );

and then later

call sa_server_option ( 'RequestLogging', 'NONE' );
Breck_Carter
Participant

The name @p0 looks like a variable name, not a column name in a table.

However, if the variable name is used inside a SELECT or other kind of query (a DELETE WHERE clause for example), and the variable has not been declared, SQL Anywhere may try (and fail) to find the name among all the columns in the tables... and then issue this confusing message.

MarkCulp
Participant

The @p0 is a parameter name, often used by TSQL connections. This error could be related to the fact that tsql_variables has not been set to 'ON' (because sp_tsql_environment procedure was not executed) - see http://dcx.sap.com/index.html#sqla170/en/html/81523aa06ce210148cedcced6951b23e.html*loio81523aa06ce2...

VolkerBarth
Contributor

So that behaviour (which I was completely unaware of) might be a reason to leave the login procedure as is and just try to adapt the isolation level via a table hint - or to check what options set by the login procedure should be reset afterwards...

fvestjens
Participant

Could the jdbc driver be the problem when it is not a sql anywhere 9 version?

Is this driver still available? was it on the original CD?

VolkerBarth
Contributor

Have you checked whether the isolation level is set differently? I'm not sure but the default isolation level is 0 (which allows dirty reads, say against a freshly inserted row) whereas the JDBC driver might use isolation level 1 by default, meaning it would possibly be blocked during such a read...

As Breck has stated, please show us what the INSERT and the according trigger and procedure really do.

fvestjens
Participant
0 Kudos

Regarding the isolation level. Should it be changed on the client side or should it be set at the beginning of the procedure?

fvestjens
Participant
0 Kudos

We'll force the isolation level in the JDBC driver to 0 and see what happens