Avatar billede fredand Forsker
01. november 2004 - 19:32 Der er 7 kommentarer og
1 løsning

How to create a Rollback with MySQL and Java? (test source valid)

/*
Hello!
I try to find out how to use real transactions with Java and a MySQL database.
With transaction I mean that if a insert or update is done and we got a exception occurs before an other
insert or update is done we will be able to undo the first insert or update (a rollback).

But I do not manage to create a rollback.
What I want to do is to run a rollback when a Exception occurs.

Below is my full test code ready to use, which I thought would do a rollback but it doesn't. The first insert will be commited any way.

My tables in a database in MySQL looks like:

CREATE TABLE test1
(
id INT NOT NULL AUTO_INCREMENT,
date DATETIME NOT NULL,
PRIMARY KEY(id)
);

CREATE TABLE test2
(
id INT NOT NULL AUTO_INCREMENT,
test1_id INT NOT NULL,
PRIMARY KEY(id),
FOREIGN KEY (test1_id) REFERENCES test1(id)
);

To connect to this database I use a properties file thats looks like:
dbDriver            com.mysql.jdbc.Driver
dbConnectionString    jdbc:mysql://localhost/my_test_database?user=root&password=my_pass

So if any one could tell me how to create a rollback or tell me if there is a bug please let me know.

Unfortunally I do not use the latest MySQL database, but I use the latest jdbc-driver. And I also use Java 1.4.0.

Best regards
Fredrik


*/


import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;
import java.sql.*;

public class GuestTest2
{
    public static void main(String[] args)
    {
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;

        /*
        This block insert 1 row in table test1 and 1 row in table test2
        If we get a Exception there should be a rollback so all changes is undone.

        To create a exception we can comment the row
        preparedStatement.setInt(1, id.intValue());
        to
        //preparedStatement.setInt(1, id.intValue());
        */
        try
        {
            Class.forName("com.mysql.jdbc.Driver");
            connection = DriverManager.getConnection("jdbc:mysql://localhost/internetprogrammering_uppgift6?user=root&password=pass");
            connection.setAutoCommit(false);
            preparedStatement = connection.prepareStatement("INSERT INTO test1 (date) VALUES(?)");
            preparedStatement.setTimestamp(1, new Timestamp(System.currentTimeMillis()) );
            preparedStatement.execute();

            preparedStatement = connection.prepareStatement("SELECT MAX(id) FROM test1");
            preparedStatement.execute();
            resultSet = preparedStatement.getResultSet();
            resultSet.next();
            Integer id = (Integer)resultSet.getObject(1);

            preparedStatement = connection.prepareStatement("INSERT INTO test2 (test1_id) VALUES(?)");
            //Comment row below to create a exception
            preparedStatement.setInt(1, id.intValue());
            preparedStatement.execute();

            connection.commit();

            resultSet.close();
            preparedStatement.close();
            connection.close();
        }
        catch(Exception e1)
        {
            e1.printStackTrace();
            try
            {
                System.out.println("Rollback");
                connection.rollback();
                connection.commit();
            }
            catch(Exception e2)
            {
                e2.printStackTrace();
            }
        }
        finally
        {
            try
            {
                if(resultSet != null)
                {
                    resultSet.close();
                }
                if(preparedStatement != null)
                {
                    preparedStatement.close();
                }
                if(connection != null)
                {
                    connection.close();
                }
            }
            catch(Exception e2)
            {
                e2.printStackTrace();
            }
        }


        /*
        This section shows whats in the database after insert with or with out rollbacks.
        */
        try
        {
            Class.forName("com.mysql.jdbc.Driver");
            connection = DriverManager.getConnection("jdbc:mysql://localhost/internetprogrammering_uppgift5?user=root&password=snuffa");
            preparedStatement = connection.prepareStatement("SELECT * FROM test1");
            preparedStatement.execute();
            resultSet = preparedStatement.getResultSet();
            while( resultSet.next() )
            {
                StringBuffer stringBuffer = new StringBuffer();
                stringBuffer.append(resultSet.getString(1));
                stringBuffer.append(" ");
                stringBuffer.append(resultSet.getString(2));
                System.out.println( stringBuffer.toString() );
            }

            resultSet.close();
            preparedStatement.close();
            connection.close();
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
        finally
        {
            try
            {
                if(resultSet != null)
                {
                    resultSet.close();
                }
                if(preparedStatement != null)
                {
                    preparedStatement.close();
                }
                if(connection != null)
                {
                    connection.close();
                }
            }
            catch(Exception e2)
            {
                e2.printStackTrace();
            }
        }
    }

}
Avatar billede arne_v Ekspert
01. november 2004 - 19:38 #1
What should happend and what does happend ?

I assume that you are using InnoDB tabels since MyISAM does not support transactions.

You should not call commit after calling rollback.
Avatar billede fredand Forsker
01. november 2004 - 20:10 #2
Hello!

What should happens:
one insert into table 1
if a exception occurs before next insert into table 2 a rollback should take place

What happens
one insert into table 1
when a exception occours and the rollback is called (with our with out the commit afterwards) the insert into table 1 remains.

the commit after the rollback is just for testing.

I use MySQL 3.23 so I'm not sure I use InnoDB but I guess I do cause I remeber I have seen something about InnoDB from some other exceptions earlier.

Is there some way to check that for sure?

Best regards
Fredrik 

BTW I said something about some properties file that I use for conncet I now see in the code above that I do not, sorry!
Avatar billede arne_v Ekspert
01. november 2004 - 20:23 #3
SHOW CREATE TABLE tabelnavn;

viser også tabel type
Avatar billede fredand Forsker
02. november 2004 - 07:33 #4
Hello!

I tried what you said and found out that it is: TYPE=MyISAM

So is it possible to change or do I just have to use an newer version of MySQL?

And if you took a look at the code above, do you think that it should work if I manage to change it to InnoDB?

Best regards
Fredrik
Avatar billede arne_v Ekspert
02. november 2004 - 07:41 #5
In version 3.x I belive that you have to use MySQL-MAX to have InnoDB support.

According to http://dev.mysql.com/doc/mysql/en/Storage_engines.html you can convert
with an ALTER TABLE statement.
Avatar billede fredand Forsker
02. november 2004 - 20:01 #6
Hello!
The error was the type of DB. At first I did not used InnoDB but after I have created a my.cnf file and restarted the MySQl database with --defaults-extra-file=C:/mysql/data/my.cnf
I could create my tables like:

CREATE TABLE test1
(
id INT NOT NULL AUTO_INCREMENT,
date DATETIME NOT NULL,
PRIMARY KEY(id)
)
TYPE = INNODB;

CREATE TABLE test2
(
id INT NOT NULL AUTO_INCREMENT,
test1_id INT NOT NULL,
PRIMARY KEY(id)
)
TYPE = INNODB;

After that everything worked fine if I got a exception and needed to do a rollback.

Best regards
Fredrik


Please give me a svar so I can reward you!
Avatar billede arne_v Ekspert
02. november 2004 - 20:30 #7
here it comes
Avatar billede fredand Forsker
03. november 2004 - 07:43 #8
Thanks mate!

/Fredrik
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester