SQL Server Forum / Programming / Connectivity / January 2006
Behavior of Connection.commit()
|
|
Thread rating:  |
Wes Clark - 20 Jan 2006 17:32 GMT Running with "SET IMPLICIT_TRANSACTIONS ON", with the old driver we would sometimes issue a commit on a connection when no work had been done on the connection, and we would never get "Msg 3902, Level 16, State 1, Line 1 The COMMIT TRANSACTION request has no corresponding BEGIN TRANSACTION." We are now getting this message. Did the old driver know no statements had been issued on the connection since the last commit, and not issue the command to the server? We use a framework do manage the database interface.
Wes Clark - 20 Jan 2006 18:03 GMT Actually, we call setAutoCommit(false) on the connection, we don't issue "SET IMPLICIT_TRANSACTIONS ON" via sql.
Joe Weinstein - 20 Jan 2006 18:16 GMT > Actually, we call setAutoCommit(false) on the connection, we don't issue "SET > IMPLICIT_TRANSACTIONS ON" via sql. Whew, good. I'm sure you know how bad form it would be to mix transactional control between JDBC and DBMS-specific SQL. (I've seen it done!). Can you verify that you *always* call setAutoCommit(false) before calling commit()? thanks, Joe Weinstein at BEA Systems
Jerry Brenner - 20 Jan 2006 18:25 GMT Joe, funny meeting you here.
We call setAutoCommit(false) when we first get a connection, just prior to putting it into the connection pool. If we need to change it for some reason, then we always change it back before committing.
> > Actually, we call setAutoCommit(false) on the connection, we don't issue "SET > > IMPLICIT_TRANSACTIONS ON" via sql. [quoted text clipped - 4 lines] > thanks, > Joe Weinstein at BEA Systems Joe Weinstein - 20 Jan 2006 18:42 GMT > Joe, funny meeting you here. > > We call setAutoCommit(false) when we first get a connection, just prior to > putting it into the connection pool. If we need to change it for some > reason, then we always change it back before committing. Hi Jerry! Good to hear from you, and MS will benefit greatly by working with you on driver/DBMS query plan issues... I am unable to duplicate the problem with the commit() call with some cheap JDBC I tried... If you can provide a repro or trace the execution history of a connection that throws this exception, that would be cool.
Email me j o e AT b e a DOT c o m
>>>Actually, we call setAutoCommit(false) on the connection, we don't issue "SET >>>IMPLICIT_TRANSACTIONS ON" via sql. [quoted text clipped - 4 lines] >>thanks, >>Joe Weinstein at BEA Systems Angel Saenz-Badillos[MS] - 20 Jan 2006 19:45 GMT "The COMMIT TRANSACTION request has no corresponding BEGIN TRANSACTION."
This could be a very serious error. This may not be what is affecting your scenario but here is some information that may be applicable. The basic problem is that high severity SQL exceptions (level 16 or higher) can rollback the transaction on the server. When this happens the old driver was masking the error during COMMIT with something like the following TSQL:
IF @@TRANCOUNT > 0 COMMIT TRAN //If there is a transaction active commit it, otherwise do nothing.
We decided that faking a transaction commit was a bad idea and in the new driver replaced it with something like: COMMIT TRAN //Commit transaction, if no transaction active throw exception.
What this means is that the following scenario would behave
//start transaction //insert data 1 //execute something that throws lev 16 server exception and ignore exception. At this time insert data 1 has been rolled back! //insert data 2 //COMMIT
In the old driver in this scenario commit would silently "work" (not throw an exception), even though insert data 1 has been rolled back. In the new driver this will now throw an exception and you will at least know that not all is well. We felt that it was an important breaking change to make.
 Signature Angel Saenz-Badillos [MS] DataWorks This posting is provided "AS IS", with no warranties, and confers no rights.Please do not send email directly to this alias. This alias is for newsgroup purposes only. I am now blogging: http://weblogs.asp.net/angelsb/
>> Joe, funny meeting you here. >> [quoted text clipped - 31 lines] >>>thanks, >>>Joe Weinstein at BEA Systems Joe Weinstein - 20 Jan 2006 20:18 GMT > "The COMMIT TRANSACTION request has no corresponding BEGIN TRANSACTION." > [quoted text clipped - 24 lines] > driver this will now throw an exception and you will at least know that not > all is well. We felt that it was an important breaking change to make. Interesting... So what does the driver do with:
c = d.connect(URL, props); c.setAutoCommit(false); // does *not start a tx* s.commit();
Also, when the driver throws the exception above, in a circumstance you suggest, presumably the connection is still in autoCommit(false) mode. Is it?
Joe Weinstein at BEA Systems.
Angel Saenz-Badillos[MS] - 20 Jan 2006 22:48 GMT You have to remember that Sql Server does not understand the concept of a autoCommit(false) state, we have to fake this with "Begin transaction" blocks. By default the Sql Server database is in the equivalent of autoCommit(true) state, anything you do will permanently update the database.
When we set autoCommit to off the expectation is that no SQL statements will be committed (that is, the database will not be permanently updated) until you have explicitly told it to commit by invoking the commit() method. To do this in Sql Server we issue the following command to the server:
> c = d.connect(URL, props); > c.setAutoCommit(false); IF @@TRANCOUNT = 0 BEGIN TRAN //if we are currently not in a transaction, start one.
> s.commit(); COMMIT TRAN; IF @@TRANCOUNT = 0 BEGIN TRAN //Commit the existing transaction, start a new transaction to fake the fact that we are still in autoCommit(false) state.
> Also, when the driver throws the exception above, in > a circumstance you suggest, presumably the connection > is still in autoCommit(false) mode. Is it? Thanks to the BEGIN TRAN at the end of the commit it would be, but this should be no consolation. When you receive the "no corresponding begin" exception you probably have data corruption.
We recently looked into this error for a large customer. They started getting this error with our driver and filed it as a bug. When we investigated it turned out that they were doing something as inoquous as
try{ //create table }catch{ //ignore failure, this means that table already existed. }
This was sometimes running inside of a transaction, when the table was already in the database the Sql Exception would roll back the transaction but they would ignore it. With their previous driver they had no idea that everything before the above code was being rolled back.
I really should put this in an easier to read format, maybe a blog with source code you can try.
 Signature Angel Saenz-Badillos [MS] DataWorks This posting is provided "AS IS", with no warranties, and confers no rights.Please do not send email directly to this alias. This alias is for newsgroup purposes only. I am now blogging: http://weblogs.asp.net/angelsb/
>> "The COMMIT TRANSACTION request has no corresponding BEGIN TRANSACTION." >> [quoted text clipped - 39 lines] > > Joe Weinstein at BEA Systems. Joe Weinstein - 20 Jan 2006 23:20 GMT > You have to remember that Sql Server does not understand the concept of a > autoCommit(false) state, we have to fake this with "Begin transaction" [quoted text clipped - 12 lines] > IF @@TRANCOUNT = 0 BEGIN TRAN //if we are currently not in a transaction, > start one. Surely the driver can do "set implicit_transactions on" instead of that. My old driver from '96 does this:
setAutoCommit(true): "if (@@trancount > 0) rollback transaction set implicit_transactions off" setAutoCommit(false): "if (@@trancount > 0) rollback transaction set implicit_transactions on"
Joe Weinstein at BEA Systems
>>s.commit(); > [quoted text clipped - 26 lines] > I really should put this in an easier to read format, maybe a blog with > source code you can try. Angel Saenz-Badillos[MS] - 20 Jan 2006 23:25 GMT Just a quick repro program that explains the problem, I would be interested to see how other Sql Server drivers handle this:
import java.lang.*; import java.util.*; import java.sql.*; import java.math.*; import java.text.*; import java.io.*;
public class test { public static String ConnectionString = "<set your connection string here>";
public static void main(String[] args) throws Exception { Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); Connection conn = DriverManager.getConnection(ConnectionString); Statement stmt = conn.createStatement(); String tablename= "testTX"; stmt.executeUpdate("if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[" + tablename + "]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) DROP TABLE [" + tablename + "]"); stmt.executeUpdate("CREATE TABLE [" + tablename + "] (a int)");
conn.setAutoCommit(false); stmt.executeUpdate("INSERT into [" + tablename+ "] values (1)"); try{ //This will kill the transaction! stmt.executeUpdate("CREATE TABLE [" + tablename + "] (a int)"); }catch(Exception ex){System.out.println(ex.getMessage());} stmt.executeUpdate("INSERT into [" + tablename+ "] values (99999)"); try{ conn.commit(); }catch(Exception ex){System.out.println("We correctly throw an exception: "+ex.getMessage());} conn.close();
//Verify data inserted. Connection conn2 = DriverManager.getConnection(ConnectionString); Statement stmt2 = conn2.createStatement(); ResultSet rs = stmt2.executeQuery("SELECT * FROM [" + tablename + "]"); while(rs.next()){ System.out.println(rs.getObject(1)); } System.out.println("If this did not print out 2 lines: 1, 99999 you have data corruption."); } }
 Signature Angel Saenz-Badillos [MS] DataWorks This posting is provided "AS IS", with no warranties, and confers no rights.Please do not send email directly to this alias. This alias is for newsgroup purposes only. I am now blogging: http://weblogs.asp.net/angelsb/
>> You have to remember that Sql Server does not understand the concept of a >> autoCommit(false) state, we have to fake this with "Begin transaction" [quoted text clipped - 54 lines] >> I really should put this in an easier to read format, maybe a blog with >> source code you can try. Joe Weinstein - 20 Jan 2006 23:51 GMT Ok, I just tested another driver that fails the tx because the table is there. The subsequent commit does not fail. The select gives only the 9999 row. I don't understand how your program expects the commit to fail, but then expects the row inserted in a failed tx to still be there? Joe
> Just a quick repro program that explains the problem, I would be interested > to see how other Sql Server drivers handle this: [quoted text clipped - 46 lines] > } > } Angel Saenz-Badillos[MS] - 21 Jan 2006 00:04 GMT Thank you for taking the time to test this with another driver. The intention of the program is to show that with this driver when you get this type of data corruption we will throw on Commit. It is an ugly problem, but to us it seemed like a better option than having commit succeed and silently corrupting your data.
This is why I mentioned that this could be a very serious error, your code could be silently corrupting your data with your previous driver. With this driver you can at least realize that there may be a problem but it will probably require code changes to fix the underlying issue.
>I don't understand > how your program expects the commit to fail, but > then expects the row inserted in a failed tx to still > be there? I am sorry for not making it clearer, I am afraid I just threw it together to post it while everybody is looking at this thread. The program was intended to show that others drivers that don't throw on commit still have the same data corruption issue.
 Signature Angel Saenz-Badillos [MS] DataWorks This posting is provided "AS IS", with no warranties, and confers no rights.Please do not send email directly to this alias. This alias is for newsgroup purposes only. I am now blogging: http://weblogs.asp.net/angelsb/
> Ok, I just tested another driver that fails the tx because > the table is there. The subsequent commit does not fail. [quoted text clipped - 54 lines] >> } >> } Joe Weinstein - 21 Jan 2006 00:58 GMT > Thank you for taking the time to test this with another driver. The > intention of the program is to show that with this driver when you get this [quoted text clipped - 6 lines] > driver you can at least realize that there may be a problem but it will > probably require code changes to fix the underlying issue. Understood. It is in fact the DBMS that throws us all most of the curve balls. The DBMS should treat every SQL failure the same. If somewhere in a tx we try to insert a value into a row where it doesn't fit, we get an exception, but the tx is still alive for us to pursue or close as we see fit. In the rare case where someone tries DDL in a transaction, it shouldn't logically be any different. I I alter the program so the failure is updating a varchar(1) to be '333', it also throws an exception, but afterwards I am able to commit or rollback as I choose. So, the driver author's problem is what to do... I would code to at least support the mode where any unexepected SQLException is reacted to by a rollback(). However, I agree that for those 'executive decisions' the DBMS will make, to roll back your exception immediately, the driver should make any immediate commit() fail, and have it say "Commit failed because current tx was chosen as a deadlock victim", or Commit failed because DDL-in-tran failed". This info would have to be cached by the driver from the exception during the execute call, and then serve it up on commit... (Joe say thinking thinly while typing...) Joe
>>I don't understand >>how your program expects the commit to fail, but [quoted text clipped - 5 lines] > intended to show that others drivers that don't throw on commit still have > the same data corruption issue. Sam Wilson - 21 Jan 2006 01:59 GMT I'm with Joe... I'm a bit concerned why the driver doesn't issue "set implicit_transactions on" which is the logical equivalent of setAutoCommit(false).
Am I missing something or is this functionality not analogous??
Thanks,
Sam Wilson Ecount, Inc.
> > You have to remember that Sql Server does not understand the concept of a > > autoCommit(false) state, we have to fake this with "Begin transaction" [quoted text clipped - 51 lines] > > I really should put this in an easier to read format, maybe a blog with > > source code you can try. Angel Saenz-Badillos[MS] - 23 Jan 2006 19:11 GMT Sam, The problem is the same as above. If we set set_implicit_transactions on we will no longer be able to tell that a serious issue happened on commit and we would not throw an exception:
//start transaction //insert data 1 //execute ddl exception. At this time insert data 1 has been rolled back! //insert data 2 //with set_implicit_transactions on this will create a NEW transaction under the covers. //COMMIT will no longer throw an exception, it will commit the transaction started with insert data 2 and you will silently ignore the fact that data 1 has been rolled back.
 Signature Angel Saenz-Badillos [MS] DataWorks This posting is provided "AS IS", with no warranties, and confers no rights.Please do not send email directly to this alias. This alias is for newsgroup purposes only. I am now blogging: http://weblogs.asp.net/angelsb/
> I'm with Joe... I'm a bit concerned why the driver doesn't issue "set > implicit_transactions on" which is the logical equivalent of [quoted text clipped - 73 lines] >> > I really should put this in an easier to read format, maybe a blog with >> > source code you can try. Joe Weinstein - 23 Jan 2006 19:48 GMT > Sam, > The problem is the same as above. If we set set_implicit_transactions on we [quoted text clipped - 7 lines] > //insert data 2 //with set_implicit_transactions on this will create a NEW > transaction under the covers. Understood. One other thing to consider is if the driver can know from the DBMS message when (the rare case such as deadlock or DDL) when the DBMS has already killed the whole tx, and in that case, throw an exception from any subsequent connection, statement or result set method that would/could do an update or query (because it may hold locks) (from this connection) saying "The DBMS has killed the current transaction. No further DBMS access is allowed until you call rollback()".
> //COMMIT will no longer throw an exception, it will commit the transaction > started with insert data 2 and you will silently ignore the fact that data 1 > has been rolled back. Correct, but there is a problem as soon as the tx has been rolled back, and there can be troubles even allowing the insert data 2 to proceed. The user application may depend on holding locks in order, and once it is allowed to proceed obtaining the lock for data 2, it may then go on to obtain other locks before trying to commit, and this not-expected order of locking (data 1 and any other data previously locked are now unlocked) may cause deadlocks that could kill other innocent, correct transactions. HTH, Joe
Angel Saenz-Badillos[MS] - 23 Jan 2006 20:21 GMT This is completely correct; throwing an exception on commit is only a band aid and still causes too much pain.
>throw an exception from any subsequent connection, statement or result
>set >method that would/could do an update or query This would be the only real solution to this problem. The big IF of course is whether we can correctly determine all cases in which the transaction has been rolled back by the DBMS...
 Signature Angel Saenz-Badillos [MS] DataWorks This posting is provided "AS IS", with no warranties, and confers no rights.Please do not send email directly to this alias. This alias is for newsgroup purposes only. I am now blogging: http://weblogs.asp.net/angelsb/
>> Sam, >> The problem is the same as above. If we set set_implicit_transactions on [quoted text clipped - 30 lines] > HTH, > Joe Wes Clark - 24 Jan 2006 22:59 GMT It turns out in very limited circumstances in a few test programs, we were sending a "commit" sql statement to the database. A developer found this in a trace we send in. This was messing up the driver. And I don't think this is related to most of the discussion on this thread.
I would suggest that if the driver needs to keep track of the state of the transaction, it would be advisable to look for SQL statements that would affect that state. I don’t think the JDBC spec would say you can’t commit a transaction using the SQL.
I imagine the other drivers do that very thing. Do you accept this as a “bug” and/or should I enter this somewhere else?
Thank you for helping us get back on the road.
Joe Weinstein - 24 Jan 2006 23:29 GMT > It turns out in very limited circumstances in a few test programs, we were > sending a "commit" sql statement to the database. A developer found this in [quoted text clipped - 5 lines] > affect that state. I don’t think the JDBC spec would say you can’t commit a > transaction using the SQL. I'd take the other position. The load imposed by the driver having to parse all the SQL, looking for commits, rollbacks etc in SQL would be onerous and inappropriate. It would be clearly poor style to distribute control of transactions between JDBC and SQL. Procedures could have 'commit' in them and the driver could never know.
> I imagine the other drivers do that very thing. Do you accept this as a > “bug” and/or should I enter this somewhere else? They don't. I highly recommend controling your transactions within a top-level method that does all the tx work and then calls commit() or rollback, or letting a tx-capable container do it all for you. Joe Weinstein at BEA Systems
> Thank you for helping us get back on the road. Wes Clark - 25 Jan 2006 00:37 GMT I'm interested in Microsoft's response. Does anyone know what the JDBC spec says here? Does it say "commit" and "rollback" and other SQL commands that affect the transaction state are not allowed? If so, should the driver throw an error? That would also require parsing, of course.
How about in a batch of statements? How sure can the driver ever be about the state of the transaction?
> > It turns out in very limited circumstances in a few test programs, we were > > sending a "commit" sql statement to the database. A developer found this in [quoted text clipped - 21 lines] > > > Thank you for helping us get back on the road. Joe Weinstein - 25 Jan 2006 01:20 GMT > I'm interested in Microsoft's response. Does anyone know what the JDBC spec > says here? Does it say "commit" and "rollback" and other SQL commands that [quoted text clipped - 3 lines] > How about in a batch of statements? How sure can the driver ever be about > the state of the transaction? We will await MS's response. In the meantime, the spec says nothing. It also doesn't say what happens if the JDBC driver sends "shutdown" SQL to the DBMS either. A batch of statements doesn't add any more complexity. The driver must assume the transactional status is as it was set the last time via JDBC. Drivers will never parse SQL for transactional semantics, let alone presume to react to them, and stored procedures or even triggers could easily subvert any such effort. I can promise you as a former JDBC spec member and co-author of the first commercial JDBC drivers on the market for MS SQLServer, Sybase, Oracle, and Informix, and as a DBMS guy (joe@sybase.com '88-'96) that you should always define, control and terminate a tx with only one API and in one logical place. Good luck, I want you to be successful. Joe Weinstein at BEA Systems
>>>It turns out in very limited circumstances in a few test programs, we were >>>sending a "commit" sql statement to the database. A developer found this in [quoted text clipped - 21 lines] >> >>>Thank you for helping us get back on the road. Angel Saenz-Badillos[MS] - 25 Jan 2006 01:37 GMT We will definitelly be looking at this and the separate issue with exceptions, I am glad to hear that the inmediate issue at least is resolved.
I can't think of a single driver in existance today for Sql Server that handles both TSQL and API transaction handling simultaneously, making this scenario work is going to be very tough. One thing we _could_ do would be to throw an exception whenever we detect that this is happening, so we could only begin, roll back, and commit transactions after verifying that the transaction count on the server is what we expect at that point in time.... On the other hand this could be even more damaging...
 Signature Angel Saenz-Badillos [MS] DataWorks This posting is provided "AS IS", with no warranties, and confers no rights.Please do not send email directly to this alias. This alias is for newsgroup purposes only. I am now blogging: http://weblogs.asp.net/angelsb/
>> I'm interested in Microsoft's response. Does anyone know what the JDBC >> spec says here? Does it say "commit" and "rollback" and other SQL [quoted text clipped - 54 lines] >>> >>>>Thank you for helping us get back on the road. Joe Weinstein - 25 Jan 2006 02:13 GMT > We will definitely be looking at this and the separate issue with > exceptions, I am glad to hear that the inmediate issue at least is resolved. > > I can't think of a single driver in existance today for Sql Server that > handles both TSQL and API transaction handling simultaneously, For *any* DBMS, and I work on Oracle's thin driver and Sybase's jConnect driver regularly, as well as debugging ours for DB2, etc.
> making this > scenario work is going to be very tough. One thing we _could_ do would be to > throw an exception whenever we detect that this is happening, so we could > only begin, roll back, and commit transactions after verifying that the > transaction count on the server is what we expect at that point in time.... > On the other hand this could be even more damaging... It would drive you nuts. You would have to postpend every execute with a query to return @@trancount and process it before the next execute from any statement, which might mean buffering tons of data etc, or even allowing a fetch from any other sensitive cursor. or even allowing the current statement to process output parameters. What if the SQL raised a fatal error after committing? You wouldn't get your post-pended @@trancount query.
"create proc my_tx_handle @whichway int as begin if (@whichway > 0)commit tran else rollback end"
"create proc my_big_tx as begin select * from the universe exec my_tx_handle 1 end"
and before processing the result set from my_big_tx the user runs another statement... etc.
And let's assume you're processing in autoCommit(true) mode, and suddenly you discover @@trancount is 3. What will the driver do? The fact is that there can only be one controller of the tx state, and if the driver isn't it, there is no way the driver can choose what to do if/when it finds it's "not in Kansas anymore". You can go only so far in protecting the user from himself without causing trouble for the normal case. Joe
Joe Weinstein - 22 Jan 2006 19:20 GMT > Surely the driver can do "set implicit_transactions on" instead of > that. My old driver from '96 does this: [quoted text clipped - 5 lines] > > Joe Weinstein at BEA Systems And just to be clear, we consciously chose to roll back any tx context that was not explicitly committed before a call to setAutoCommit(true). Some folks are used to Oracle's SQL-PLUS application committing on close, so you *could* have a connection configuration option to go the other way, but *boy* is that odd/ugly as desired behavior. For both polarities of the call, we do *not* send duplicate/redundant calls. The driver keeps a flag of the setting it's supposed to be manifesting, so whenever the user calls setAutoCommit() asking for the same mode we're already in, we do nothing. Joe
Jerry Brenner - 20 Jan 2006 22:16 GMT I'm confused by:
> What this means is that the following scenario would behave > [quoted text clipped - 4 lines] > //insert data 2 > //COMMIT If the exception from the 1st insert was a statement level exception (like duplicate key violation), then it is up to the caller to decide what to do. If the caller wants to continue, or even just call commit(), then they should be allowed to do so. However, if the exception was a transaction level exception or more severe, then a rollback should occur. Either way, autocommit should remain off on the connection, so the caller should be able to call commit() immediately.
Wes Clark - 20 Jan 2006 22:40 GMT conn.setAutoCommit(false); conn.commit(); System.out.println("Commit 1 succeeded"); conn.commit(); System.out.println("Commit 2 succeeded");
returns
Commit 1 succeeded Commit 2 succeeded
and no errors
Joe Weinstein - 20 Jan 2006 22:46 GMT > I'm confused by: > [quoted text clipped - 14 lines] > autocommit should remain off on the connection, so the caller should be able > to call commit() immediately. Right. We can cobble up an exampel with two connections and provoke a simple deadlock between them. One of them will get it's tx aborted, and we should then see whether an immediate commit() and/or rollback() gives a problem. Yes, the driver and DBMS should both still be in chained/implicit transaction/autoCommit(false) mode. Joe
Joe Weinstein - 20 Jan 2006 23:08 GMT > I'm confused by: > [quoted text clipped - 14 lines] > autocommit should remain off on the connection, so the caller should be able > to call commit() immediately. I ran the program below, in two windows, the first like:
C:\> java two_cons start
when it said to run the second, I did, like:
and the other:
C:\> java two_cons
This set up a deadlock to happen. When the second program said to press return in the first's window, I did, and it got the deadlock message. Then I checked the autoCommit() status, which was still false as far as the driver was concerned at least, and a final commit() on the connection got an exception:
trying commit... com.microsoft.sqlserver.jdbc.SQLServerException: Server failed to resume the transaction, desc: 3300000007. at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(Unknown Source ) at com.microsoft.sqlserver.jdbc.IOBuffer.processPackets(Unknown Source) at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectionCommand(Unknown Source) at com.microsoft.sqlserver.jdbc.SQLServerConnection.sendCommit(Unknown Source) at com.microsoft.sqlserver.jdbc.SQLServerConnection.commit(Unknown Source) at two_cons.main(two_cons.java:66)
Program: import java.sql.*; import java.util.*;
public class two_cons { public static void main(String args[]) throws Exception { Connection c = null; try { Properties props = new Properties(); Driver d = new com.microsoft.sqlserver.jdbc.SQLServerDriver();
props.put("user", "joe"); props.put("password", "joe"); props.put("DatabaseName", "joe");
c = d.connect("jdbc:sqlserver://joe:1433", props );
DatabaseMetaData dd = c.getMetaData(); System.out.println("Driver version is " + dd.getDriverVersion() );
Statement s = c.createStatement();
if (args.length != 0) { try {s.executeUpdate("drop table joe");}catch (Exception ignore){} try {s.executeUpdate("drop table joe2");}catch (Exception ignore){} s.executeUpdate("create table joe(foo int)"); s.executeUpdate("insert joe values(1)"); s.executeUpdate("create table joe2(foo int)"); s.executeUpdate("insert joe2 values(1)");
c.setAutoCommit(false); s.executeUpdate("update joe set foo = 2");
System.out.println("Ok, now run the other and press return"); System.in.read(); s.executeUpdate("update joe2 set foo = 2"); } else { c.setAutoCommit(false); s.executeUpdate("update joe2 set foo = 2"); System.out.println("Ok, now press return on the other");
s.executeUpdate("update joe set foo = 2"); } } catch(Exception exception1) { exception1.printStackTrace(); } finally { try { System.out.println("c.getAutoCommit() says " + c.getAutoCommit() ); } catch (Exception ee) { ee.printStackTrace(); }
try { System.out.println("trying commit..." ); c.commit(); } catch (Exception ee) { ee.printStackTrace(); } if (c != null) try {c.close();} catch (Exception ignore){} } } }
Joe Weinstein - 20 Jan 2006 23:12 GMT Oh, and if I changed the program to try to rollback instead of commit, there was *still* a problem! There's a bug. The tx *did* get rolled back because it was the deadlock victim, but as far as JDBC is concerned, the user's tx got some sort of exception, and he wants to rollback() on an autoCommit(false) connection and should be able to. Joe Weinstein at BEA Systems
>> I'm confused by: >> [quoted text clipped - 130 lines] > } > } Angel Saenz-Badillos[MS] - 20 Jan 2006 23:23 GMT Rolling back we should not see that problem, I would be very interested in getting that to repro.
 Signature Angel Saenz-Badillos [MS] DataWorks This posting is provided "AS IS", with no warranties, and confers no rights.Please do not send email directly to this alias. This alias is for newsgroup purposes only. I am now blogging: http://weblogs.asp.net/angelsb/
> Oh, and if I changed the program to try to > rollback instead of commit, there was *still* [quoted text clipped - 140 lines] >> } >> } Jerry Brenner - 20 Jan 2006 23:49 GMT I turned on the SQL Profiler and the only error that occurs is the 3902 that we are complaining about. There are no exceptions prior to that. Joe's program demonstrates a serious bug, but it looks we are hitting a different bug. Unfortunately, I we haven't been able to figure out how this unit test is different than any of the other ones that aren't failing.
Angel Saenz-Badillos[MS] - 21 Jan 2006 00:11 GMT Jerry, Thank you for taking the time to go through this. It sounds like you have a very comprehensive testing framework, if you are interested we would be happy to work with you to work through these and future issues. Feel free to contact me at the above email address (without the "online").
 Signature Angel Saenz-Badillos [MS] DataWorks This posting is provided "AS IS", with no warranties, and confers no rights.Please do not send email directly to this alias. This alias is for newsgroup purposes only. I am now blogging: http://weblogs.asp.net/angelsb/
>I turned on the SQL Profiler and the only error that occurs is the 3902 >that [quoted text clipped - 4 lines] > test > is different than any of the other ones that aren't failing.
|
|
|