Subject Re: org.firebirdsql.jdbc.FBSQLException - deadlock update conflicts with concur
Author muthu_krishnans
Is there a way do disable the MVCC and force the FB engine to behave
like a other DBs in the locking front. i.e., if a write lock for a
record is given to a transaction, let the other transaction which
needs the write lock for the same record to wait till the first
transaction is completed(Commit/Rollback).


--- In Firebird-Java@yahoogroups.com, "muthu_krishnans"
<muthu_krishnans@...> wrote:
>
> Thanks Roman, for explaining all these. Let me see what works out
for me.
>
> FYI: This simple piece of code, which doesnt have any transaction,
> generates the same exception.
>
>
> import java.sql.*;
>
> public class FirebirdIssueTest
> {
> private static int j =0;
>
> public static void main(String arg[]) throws Exception
> {
> j = Integer.parseInt(arg[0]);
> String url =
> "jdbc:firebirdsql:localhost/3050:/opt/interbase/bin/WebNmsDB";
> try
> {
> Class.forName("org.firebirdsql.jdbc.FBDriver");
> }
> catch (ClassNotFoundException cnfex)
> {
> System.err.println("Not found the class.");
> }
> Connection c = DriverManager.getConnection(url, "sysdba",
> "masterkey");
> Connection c1 = DriverManager.getConnection(url, "sysdba",
> "masterkey");
> final PreparedStatement ps = c.prepareStatement("update
> TestTable set details = ? where ID = 153");
> final PreparedStatement ps1 = c1.prepareStatement("update
> TestTable set Status = ? where ID = 153");
> for(int i = 0 ; i < 2 ; i++)
> {
> Thread t = new Thread(new Runnable()
> {
> public void run()
> {
> if(j % 2 == 0)
> {
> System.err.println("Going to
> execute the statement >>>"+ (++j));
> execute(ps, "Thread"+j);
> }
> else
> {
> System.err.println("Going to
> execute the statement >>>"+ (++j));
> execute(ps1, "Thread"+j);
> }
> }
> });
> t.start();
> }
> }
>
> public static void execute(PreparedStatement ps, String val)
> {
> try
> {
> ps.setString(1, val);
> ps.execute();
> }catch(SQLException sqle)
> {
> System.err.println("Exception >>>"+ val);
> sqle.printStackTrace();
> }
> }
> }
>
>
>
>
>
>
>
> --- In Firebird-Java@yahoogroups.com, "Roman Rokytskyy"
> <rrokytskyy@> wrote:
> >
> > > Actually i dont use transaction for both the DBs.
> >
> > Ok.
> >
> > > I dont understand the reason why it allows two different
transactions
> > > to do write operation and shout on commit.
> >
> > This is called MVCC - multi-version concurrency control, MySQL has
> it only
> > for INNODB tables (which support transactions). The update creates
new
> > version of the record, which is visible only for the current
> transaction.
> > This allows other transactions to read old version of the record,
which
> > increases throughput. When transaction is committed, engine checks
> whether
> > the new version is the next version, or some concurrent
transaction has
> > updated the same record and already committed.
> >
> > There is a plenty of information on this topic, why it is better,
> how it
> > works and what might be the issues.
> >
> > But anyway, it does not apply to you, since you do not use
> transactions at
> > all.
> >
> > > I dont use tranastion, so implicitly it should be auto-commited,
> isnt it?
> >
> > Yes.
> >
> > Ok. Now, most likely your situation is the following. Firebird
does not
> > support auto-commit at all, and JDBC driver emulates it by starting a
> > transaction before executing the statement, and committing right
> after the
> > execution. For me this is the only reason why it happens - it is not
> related
> > to locking the record on reading, since you do not use transactions.
> >
> > So I assume that you update data very intensively, and MySQL
> executed them
> > sequentially. Firebird tries to execute them in parallel, but then
some
> > updates conflict.
> >
> > So, the easiest thing for you is to execute failed update again. But
> again,
> > I assumed simple situation, your system might look differently...
> >
> > Roman
> >
>