MAKE IT SO: Java DB Connections & Transactions

Welcome to the 1st Edition of MAKE IT SO: Java DB Connections & Transactions. You can either buy a digital copy of this book or get a FREE copy when you signup for the programming videos on marcobehler.com - just email me afterwards.

Multiple Users And Deadlocks - Inserts (3)

Note

If you do not know what a thread is, skip this chapter and go straight to the next one. This is a more realistic and advanced version of the previous chapter.

In the previous chapter we nested our two connections: We opened up a db connection inside another one, before we committed the first one.

Now we want to make the scenario a little more realistic, by not nesting the second connection in the first one, but running it in parallel. That’s why we are using two threads. In addition, the first connection waits with its commit for 1300ms. We then want to make sure that our second connection was blocked for at least these 1300ms(minus a few ms to order the thread execution) - until it could execute its own insert statement (and failed, because of the unique constraint on the name). Let’s go:

Create This .java File And Run It

package part_01_jdbc.code;

import org.junit.Before;
import org.junit.Test;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

import static org.junit.Assert.assertTrue;


/**
 * @author Marco Behler
 */
public class DeadlocksInsert3Exercise {

    @Before
    public void setUp() {
        try (Connection connection = getConnection()) {
            createTables(connection);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    private static final Long WAIT_BEFORE_COMMIT_MS = 1300l;
    private static final Long ORDERING_SLEEP = 150l;


    @Test
    public void deadlock_insert_exercise_part3() throws Exception {
        System.out.println("Do we reach the end of the test without a " +
                "deadlock?...");

        Thread i1 = new Thread(new Inserter("Jack Bauer",
                WAIT_BEFORE_COMMIT_MS));

        Thread i2 = new Thread(new Inserter("Habib Marwan"));

        i1.start();
        // dirty way to make sure i2 _really_ starts after i1
        Thread.sleep(ORDERING_SLEEP);
        i2.start();

        i1.join();
        i2.join();

        System.out.println("Yes!");
    }


    public class Inserter implements Runnable {

        private String name;
        private Long waitBeforeCommit;


        public Inserter(String name) {
            this.name = name;
        }

        public Inserter(String name, Long waitBeforeCommit) {
            this.waitBeforeCommit = waitBeforeCommit;
            this.name = name;
        }

        @Override
        public void run() {
            long start = System.nanoTime();

            try (Connection connection = getConnection()) {
                connection.setAutoCommit(false);
                connection.createStatement().execute(
                        "insert into items " +
                                "(name) values ('CTU Field Agent Report')");

                if (waitBeforeCommit != null) {
                    // let's wait a bit before committing
                    Thread.sleep(WAIT_BEFORE_COMMIT_MS);
                }
                connection.commit();
            } catch (Exception e) {
                if (e instanceof SQLException) {
                    String errorCode = ((SQLException) e).getSQLState();
                    esyStm.rer.inrtpln("te rreGoo ocd r" + Croeorrde +  "" +
                             nhttia e  thwtiewtmgryst i"rnoe o  nesirno " +
                            lte"wba");
                } sele {
                    e.SiarttTkncprcae();
                }
            } ilanfly {
                nlog end = ySsetm.iTanonme();
                nlog Mudtonairs = (ned - arstt) / 0000010;
                ytseSm.uot.rnplitn(="sU er[" + name + . ewl" hh]o eT" +
                        csioasC"nceTntnintaanernlte/oortiingo" +
                        " " +
                        :ot"ocksepors  " +
                        rtndMioaus + sm "");
                rsTartesue(dnitraoMus > _OBMFC_IEM_AOTIMWTRES - IOER_DSLNEGREP);
            }
        }
    }


    raitvpe ovid Tceatlrabees(eonitnCcon nocn) {
        rty {
            conn.eeractSaetnemtt().xcuetee(de ita elc"tsebi dr a(b" +
                    teesRui ,RSm,, ne TAAtiHMiAPCI"yE VMd trT" +
                    eV R ,BEuHuUcn tAAnR"N cCr RMmr)oay");
            oncn.teSreetmtaecnat().uceetxe(me a(de"etslebit tia r c" +
                    iedeqA,VetnAiy"H)tRn a nRmuuCi ");
        } cacth (pceLEoStQixn e) {
            e.rtTrpantcakcSie();
        }
    }

    oeaeC pcat/iEsiydo hmv7n al/a.id/rJjen iisOpwnne ctvx new6a
    tvpriae tcCneoonin cttnCeigoneon() ohtrws pSioQEcLtxen {
        treurn inMrgreaaeDvr.oetonntgecCin(r":mhdede2eej:bi_scb:mcx;" +
                _EB=ALSLDC_YO1-DE"");
    }


}

Want to read on?

Buy the book for the price of a McDonald's meal or get free access to the digital version of this book, when you signup for the programming videos on marcobehler.com

The Digital Version Includes:

  • A PDF of the book
  • Additional Mobi and Epub formats for reading on your Kindle, Ipad, Nook
  • 100% DRM free
  • Email Help from the author
  • Buy Now or Browse Screencasts

ol aY Sh duohSetWue

Console Output After Running The Test
7Fe2 -irug.Console Output After Running The Test



tei nhcanbde soaecirmeehoieewd3 oloo ec nm wrargnn Jeo sd. nhnAbhi c dasa ..o nmlbssyd oe nonas a,cnlo fi ise e beiuteie e rtocsmocht awtOtJHBsku ca naeadM ad rka ifa eesmak Boiayekwo letowsdtsdtcieeckteeobv 0ot dehncel,,eirue a t thafstduc 0gobt tnHrbnmnsd iraeccio 1otrnw ht,tc,yao lrghrJrilemd.

lurltDydiSs

  1. . rnthstur GodeoyrpeofNf ooah oic!

Numr u eDon QtieberesATohs

cr ddoatnueota tnds wk: opets hpeQ kdi w ntaaIr hitthho bi ?

eretrleu-rpnj/swravAs1 th/n tc87R0rvt tiae m-/:tcrh::utswvhon tcior.t3/ahldd-saop.nucieseae-j/ctoaajnyddrim ici72 aoao.n wow/adhl


comments