I am facing some problems when executing a rollback operation in a unit test. The unit test consists of the following steps:
The first execution works. But if you try to execute it again, this second execution throws a not unique primary key exception (UltraliteJ Error -193) when executing the second step, so the rollback operation (5th step) does not work propertly on the first execution. If I executes a checkpoint operation at the end of the test all executions works fine. Is this really necessary? Is there a way (UltraliteJ api) to always checkpoint after commit and rollback? I try to use setAutocheckpoint method in the ConfigFileAndroid object, but it does not work. Do I need to set "commit-flush" property to "immediate"? How can I do this? Thank you, Ericsen |
I was able to reproduce this problem. Thanks Renato. There is currently a bug with DatabaseManager.release() - it finalizes an object in libultralitej12.so, making the shared library unusable, even after the application is closed and restarted. That is because the process that loaded the shared libray is still active even after the application is closed. I will fix that bug. In the meantime, I recommend not using DatabaseManager.release(), but release()-ing all database connections in the application's onDestroy(). If you see a problem when using this approach, please let us know. FYI: The problem with DatabaseManager.release() is fixed in 12.0.1.3713 or later. This method will be useful for releasing active connections in this build. Question for Ericsen: Were you using DatabaseManager.release() in your application when you originally posted this issue? If not, we would need your complete application in order to see how the application closes and starts again. Note: the ~db file is a temporary file, and it is expected that it will remain if the application closes without releasing its connections. The temp file remaining is not harmful, but we do recommend that applications release active connections in the onDestroy() method of the activity.
(30 Mar '12, 11:38)
Andy Quick
|
Just to clarify, let's assume the last id is 1. After the first run, I would expect there to be a row with id = 2.
Then on the second run I would expect the following:
Are you creating Conn1 and Conn2 on separate threads? Between runs, did you do a SELECT id FROM table to verify there is in fact no IDs? Can you post the API you used for step 5? 1
I am not creating conn1 and conn2 on separate threads. I check results with SELECT statements after each INSERT statement. I execute a "SELECT MAX(id) FROM table" to get the last id. On the second run the last id is 2 (correctly). But when I try to insert id=3 I got the exception. I create my connections right before the insert statements. And I close them right after the commit and rollback statements. To execute the rollback on step 5 I execute: ulConnection.rollback(); ulConnection.release();
(31 Jan '12, 10:01)
Ericsen Cioffi
1
I am not sure whether the isolation level for UltraLite on Android is ReadCommitted (1) or ReadUncommitted (0). If it is ReadCommitted then a query on connection 1 of "SELECT MAX(id) FROM table" would not see the row inserted (but not committed) on connection 2. Attempting to insert a row with that Max(id) + 1 would then fail.
(31 Jan '12, 10:12)
Tom Slee
Replies hidden
Quick test. Try executing the SQL statement "ROLLBACK" instead of the the rollback method on the connection.
(31 Jan '12, 10:46)
PhilippeBert...
Replies hidden
Exactly the same result: first run OK (checking results) and second run fail (throws an exception) on the second step.
(31 Jan '12, 12:19)
Ericsen Cioffi
(Actually, the default is read_committed (1). "select db_property('isolation_level')" to verify.)
(03 Feb '12, 16:03)
Tim McClements
|
Hi, I created an Android project with Ericsen's test and when I launch it for the second time the exception occurs. But analyzing the code I checked that the Connection "conn1" wasn't released. After I inserted the conn1.release() the exception did not occur. But I thought, if the developer forgot to close all connections? My alternative is to put the "DatabaseManager.release();" on the "onDestroy()" method of an activity. I have tested this solution and notice that the file with <db name="">.~db continuous to be on my file folder. If I released all the connections shouldn't my <db name="">.~db file be deleted? With this file the exception still occurs. If one connection keeps holding the db resources, when I load my application again, the error will occur. I could not attach my Android Project, don't have enough reputation. tks Renato Thank you for this new information. I am reworking my test application with this new information in mind to see if I can reproduce. If I am still not able to see the problem, can you email me your project to <last_name>@sybase.com in lieu of posting. Alternatively, you can "Create a Bug Report Case" on http:\case-express.sybase.com posting the case number here for reference. There is no cost for using this service.
(23 Mar '12, 15:56)
Chris Keating
Hi Chris, Do you need the project?
(27 Mar '12, 11:52)
Renato
It would be helpful. We have not had much luck with repro'ing this issue and hope that a full project might identify what we are missing. Thanks If you can zip it up and send to <last_name>@sybase.com where last_name is my last name, I will investigate.
(27 Mar '12, 11:55)
Chris Keating
E-mail sent. tks
(28 Mar '12, 08:21)
Renato
|
Not as an answer, but have you considered to use a DEFAULT (GLOBAL) AUTOINCREMENT for the id column? This omits the manual querying of the maximum used value and solves concurreny issues...
My application and all sync logic works with a pool of primary keys. Changing to the GLOBAL AUTOINCREMENT approach is not a viable option to me.
If you are using a pool, shouldn't you be doing something like:
Conn1 mutex{ SELECT FIRST id FROM Pool (into x), DELETE FROM Poll WHERE id = x }, INSERT INTO Table( id, ... ) VALUES( x, ... )
Conn2 mutex{ SELECT FIRST id FROM Pool (into y), DELETE FROM Poll WHERE id = y }, INSERT INTO Table( id, ... ) VALUES( y, ... )
Conn1 COMMIT
Conn2 ROLLBACK
Make sure Conn2 is running with ReadCommitted isolation level.
Concurrent transactions (connections) will be common in my application and I run a lot of tests to validate this feature. This scenario is just a simplified way to reproduce a bug that I found during these tests. I need to be sure about Ultralite consistency and integrity with concurrent transactions.
Hi Ericsen,
commit-flush is immediate by default. That should not be the problem.
Can you post what connection strings you are using for all the connections?
All connections use: ";DBF=/mnt/sdcard/Android/data/myapp/files/mSeries.udb"
But you also need a CON parameter to distinguish the connections, right? Anyway, it looks like the best thing at this point would be for you to post all your code which reproduces the problem, and we'll investigate from there.
Tim, I don“t know the CON parameter. How can I set in an Android application? Can you send me a link with this parameter documentation?
To connect to the UL database I execute the following code:
Is there a better way?
(i am preparing the code to post here)
According to my new tests, if I execute concurrentTransactions method many times it will work. But if I close the application and run again it fails. It is the same scenario of the original post when I execute this steps through an Android Unit Test framework. (again, it is a simplified way to reproduce the bug)
Tim, do you have some news? Can I help you with more information?
We are looking at your repro code and will post back.
(My mistake about the CON parameter: you don't need it in this case.)
Can you confirm the version and build you are using. Testing with current software based on the sample code did not show the behaviour you described.
Chris, according to JAR Manifest file: version 12.0.1 build 3505
I have tested with current software and 12.0.1 Build 3505 on an emulator and a Galaxy Tab and do not see the problem reported. I assume I should see the primary key error first reported and/or one of the thrown exceptions in the attached code. I do not see either of those cases even after running the application n number of times where n>2.
At this stage, you may want to work with technical support if you are still running into problems.
I had exactly the same problem testing on a Nexus S Android 4.0.3 ICS, and I could reproduce the steps mentioned by Ericsen. Are you still trying to simulate the problem?
I was unable to reproduce this issue on an 4.03 based emulator. I do not have a Nexus S physical device for testing this. Can you comment on whether you see this behaviour in an simulator? If so, what specifically was used? If you are able to work with support, they can help to gather information needed to reproduced. If not, are you able to provide your repro via the free "report a bug" option on http:\case-express.sybase.com?