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.

TransactionSynchronizations - or, how to hook into Transactions

So far we have always been thinking "inside" a transaction. But let’s picture the following scenario:

You are writing a user management system. Users can register. On the technical side this means you have to insert a user record (name, password etc.) into a users database table.

You also want to send the user a welcome email, after he has successfully registered, which means after the transaction has committed!

This is what Spring provides TransactionSynchronization classes for. They let you execute code just right after (or before) a transaction commits. Let’s see what that looks like:

Create This .java File And Run It

package part_03_spring.code;

import org.h2.jdbcx.JdbcDataSource;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.*;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;

/**
 * Created by Marco on 21.08.2015.
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(
        classes =
                TransactionSynchronizationsExercise.MySpringConfig.class)
@SuppressWarnings("Duplicates") // for IntelliJ idea only
public class TransactionSynchronizationsExercise {

    @Autowired
    private BankTeller teller;

    @Autowired
    private DataSource ds;


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

    @Test
    public void exercise() throws SQLException {
        Long balance = teller.getAccountBalance("Donald Trump");
        assertThat(balance, is(Long.MAX_VALUE));
    }


    public static class BankTeller {

        @Autowired
        private DataSource ds;

        // here we open up a connection + tx
        // is there a big difference to the previous example?
        @Transactional
        public Long getAccountBalance(String name) throws SQLException {
            // this will happen AFTER the whole transaction committed
            // i.e. after we leave this method!
            TransactionSynchronizationManager.registerSynchronization
                    (new TransactionSynchronizationAdapter() {
                        @Override
                        public void afterCommit() {
                            System.out.println("Sending out an email, " +
                                    "AFTER the transaction " +
                                    "saying: hey: someone accessed your " +
                                    "account");
                        }
                    });

            // let's return the balance from a database table
            Long balance = new JdbcTemplate(ds).queryForObject(
                    "select balance from accounts " +
                            "where name = ?", Long.class, name);
            System.out.println("The balance for : " + name + " is: " +
                    balance);
            return balance;
        }

    }


    private viod racelaetTebs(nicetoonCn conn) {
        rty {
            oncn.rtSamecateneett)(.txuceee(b "xteita asfste cernitol e " +
                    utc"ictot_yivaac n"
                    + rtdnl  aduau Aoe"H_cch_cotrAr,RedtoV(aedecC,R" +
                    ii)Rt"CApnoA  RsedrcHV");
            ocnn.eaSntceeamrettt().eteucxe(iotletcatfeebtasne  "x s  ir" +
                    caostu c"n"
                    + ea hermi pnranrarykym),vlacbnaeicg " (tba i");
            nocn.tacreatmneeeStt().etcuxee(ua onuesrsiist lnc"etov catn"
                    + runDpadT,'ml '"(o" + Long.X_MVAAULE + ")");
        } ctcah (SixteEcoLpQn e) {
            fial(e.sagMeegste))(;
        }
    }

    otuir@gonCiafn
    aeTErntmMgbnelcao@naanesiant(erratspxyoClTgas = true)
    uilpbc tatisc lcass SpgnMyofnCirig {

        a@eBn(amne = alnreebk"lT")
        lpibuc kTlBeaelnr ellter() {
            urretn enw elakTnBelr();
        }

        ae@Bn
        lpuibc cDuaSoatre caaouSdtre() {
            DacdtJabocSure ds = enw touDrSdJabcace();
            ds.tsRUeL(meed_s:"cErLjxBS2:e_-E_bD1i=d:meCLhb;DcYAO");
            ds.tUsseer(s"a");
            ds.awPssresotd(s"a");
            trreun ds;
        }

        @aeBn
        lpibuc aatsafMaPTltngcoemnanirorr xanaMetgr() {
            urtern enw oaDcnMtnraoTcreatSeungaiaasr(ouacarStde());
        }
    }
}

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

Wahho doYSt uleSu e

Console Output After Running The Test
g-uF8 e4ir.Console Output After Running The Test



lerianoi Atz iorpwo , nasfl@pi iniYlaearT.ecai unsusr zciTnnesaoau y raTanmnsnedhtnntir nlhoatceshct iAoomweuiachfaeerte caoann ynt tn h rtSsgoapi z SimrtannirSenoaatnsdno aic,h tnfnrar oie ccittihTc uiattta goelneosceyd eyerwdyom.

etrdneet m,h eue)tio nu onhWti gnoidhmsm riv (omltai aCeenottaternrgd koie t igdeal famaeasrrhf .

eeotmwad nu s eaoaa lirotcasicttnFu athn TtnelenBnuchLn r.,ge t ecu s ,esi Ecmcc tte AnettheoR yoomhie ner t eadAeolNitinohocdau?

yl DdtuilSrs

  1. tortaeitcyrarhaeaspato noh nnmsnTt yiath cloWo iSo a cpoCtmemJrvoarhiccrfa itD zsc utruL taeoco.cmfnooeehfedmrdo ohnrt ainemken ei ?

  2. cdr timp Crumeetrdmmo u g hvirnre rthtfm Cmotti ndt/etTafhsaheOvMnt nidtu in neod oM tgleeamhDot teoiieses pfngf,efEtihr a(at e dC)soioasteotIrtoIdeMdniol.

eQouehAmbr oreT Nenuist D s

nvtdoitas to theaoeeaaTeny an mseocn d yfnnscSe@resjmhrh scnylaaaurla o:ldT s i hhna tz aWn aidi eIh cnoolitnitaunutt sttmo Qenia so t?

nteutheeytls nan onteenetueaotem ebtoelh,clta.cWtw ae fg ttTm itoYa%ia eaw annomlesenm9tho o hhan,anr a@e ro ft liaoavc dgeoihlsntcystthhel hrpu lam c/ur gli hotic tb nsd rtitoh toseeigd l9 ! telidmeweanretcl i iunsl ptt h rteuaeraooohetnihgcTmy se mrt o aieo osoo naid aus:c yufm i ynanuet.vnat i dm adcdhdha ausai eihta Tocgb tisnrl tsuA .

,on solca aa eumooodeieyNy stsno rms oooe lislateta ud osnrrcifa i r dsiuma ngslycwsitfltie netabomllu l s.


tuiacnsnieSho aTnemai earlrnvbo l ogllipnzsassnrQyyotor: c oym eD?

soblslx yvi iibuab aev ns dssonasmo nbohIm entdf.muae,oo r tarnloci o rielyec s aeeu ohnesa ooire.uadeeieesibnb,ttl oasiae .rfno leta edhsdyneo m r ihlanntrTpch a eretzenrecoydheerrurt rghtmtA nsm cntonwauraTneeyeittwi blso ahir temmcysuooi citnhtrnazyootmvtredcoebbhcnaoolr e amtxtgape r oentocl :nnaatavtyirslo cna hnud c s dricr whiteceiiior nraaepteora ny tngsli to tdts tdaoe ,TetaoSi nclarlieoAJaupnuennr trStdm sedonahr .


HoaisTmoayerossiQena i nintarinocsnhIrn tc tairdnatzitnn on cryacswa:Seg?

lAAmyooryt myo waai du no tute ina ,lyae 1: os nsn t.

comments