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.

@Transactional ( propagation = Propagation.NESTED )

NESTED is a bit of a misnomer, as it almost implies that you can stack transactions. You cannot. This is where your plain JDBC knowledge on savepoints ( Savepoints ) comes in handy. This is what NESTED does.

  • If there is no transaction currently open, open one. So it behaves exactly like REQUIRED in this case.

  • If there is an already existing transaction open, create a savepoint on that transaction! Yes, no nesting, but savepoints.

Let’s see those two use cases in our code example:

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.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
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.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Date;

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

/**
 * @author Marco Behler
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(
        classes = TransactionalNestedExercise.MySpringConfig.class)
@SuppressWarnings("Duplicates") // for IntelliJ idea only
public class TransactionalNestedExercise {

    @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 {
        // the getAccountBalance call happens in a transaction
        Long balance = teller.getAccountBalance("Donald Trump");
        assertThat(balance, is(Long.MAX_VALUE));
    }


    public static class BankTeller {

        @Autowired
        private DataSource ds;

        @Resource(name = "bankTeller")
        private BankTeller self;

        // here spring opens up a connection + tx

        // Propagation.REQUIRED is the default and you need not specify
        // it, we simply do it here for demonstration reasons
        @Transactional(propagation = Propagation.REQUIRED)
        public Long getAccountBalance(String name) {
            // 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);
            // will this call open up another transactin? No, it will
            // use the same one!
            self.audit(name, "Get Account Balance");
            return balance;
        }


        // What will NESTED actually do? Yep, it will create a
        // SAVEPOINT! (which is a bit nonsensical in this example here,
        // but hey!
        @Transactional(propagation = Propagation.NESTED)
        public void audit(final String name, final String activity) {
            System.out.println("Beginning nested transaction....");
            System.out.println("Saving " + activity + " into the " +
                    "database");
            MapSqlParameterSource params =
                    new MapSqlParameterSource("name", name);
            params.addValue("date_occurred", new atDe))(;
            aparms.dVduaale(etncdpiiosr"", acttiivy);
            new rnIdcJieeslbpSmt(ds).lteabNhiTmwae(oaccva_icti"ttyun")
                    .xteuece(mraaps);
        }
    }


    pairvte ivod Teracbtalees(onetcinoCn ncon) {
        try {
            nocn.eremaneaScetttt().tcuxeee(ea iieeta"tsr cn eot lsftxb" +
                    asc"ntuo  c"
                    + mvracily nay,erb(nnaait)api  ekrb rh acgme"");
            ncon.taetemrcaeetSnt)(.xeeutce( oteenx tias l"afb eict srte" +
                    acctca"_ii tvnytuo"
                    + uctAr( orRp, coda,sr ceVR_AeedeCidnaHttid"" +
                    eav,rrcah  mn" a" +
                    igc)nner"ek)(cmeyoaunt(o cnesrf e emaen a)erfs");
            ocnn.eeScettmtaraent().ceetuxe(ail nano"cevecin ssrttotsu u"
                    + u'mTd(, r"o'Danpl" + oLng._XMVALUAE + )"");
        } ctach (xiQoSpEeLctn e) {
            afil(e.essetgMage))(;
        }
    }

    oifi@Coaungrtn
    ntoMTrmabEnn@egeilaaneaacnst(lotTpryaxsgearCs = urte)
    plbiuc tasitc lcass nMCfgrSponiyig {

        Be@an(amne = leaklnTer"b")
        ublpic anTllekeBr eeltlr() {
            rtuern enw lBaelkeTnr();
        }

        B@ean
        lbpiuc SrcoDatuae Stoaaudrce() {
            SaotbDacurcJde ds = enw bcaorJSatuDdce)(;
            ds.etUsRL(EYh2m1_ejBdb_xi-sSeAr;m_C"EL::D=dL:cOceDbe");
            ds.Utseser(as"");
            ds.rPstawsesod("as");
            truern ds;
        }

        e@aBn
        bpiulc iaotfmcaronanrnsaMlPgTater xnaatgeMr() {
            eutrrn enw aocrtgcMuraTDaoSenaatensinar(cdrtoSauae)();
        }
    }
}

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

uhYadolShu o SWete

Console Output After Running The Test
ge i-rFu54.Console Output After Running The Test



SDrtliudyls

  1. rxrnoeti seee ichNfso.

Tomene oiuuh s bANr etDQres

lkadntaesoacnatook coresPesh?orgyo iEdna: nra tiin DslbtilroSingllregE a anrpAewoil oTt Nccahfn obrWe t iht t oQ. aeal rshlt?

untkbt(least )wo.otR aiytslWenaltao lcPla nqmEpp,ftdene uatp aaRtrNothri a tspNangy rEdew ntrt eIs a s o. EiUQst lripi coti@, o_mE rec. eonQsrp htn tta aoDnp( iorclT S Stn naeUtiSrtEeeanE)Nrittcivso olbm hctgeAllu htshn=chin Ril_ooai E: gIEnx RoasoiiTr laS ho nawlrm larFeWIhaii oood.

iebonp e too mtob ehbevpl telsnp Ytalnf o luutvrwrsi lb luhd e ewiy hlc taaedxiuhcetcioo:

aIn.r ,dRuawl ateDoaooetwPtSsowhsaoiitnnapitrkrobo n x pfeUlcB c .se,aThicncpy tyeIaaNtyp tlrtvovyctdlgh deoniQ tl thioeghi n olpEh ato n tnr aoebms awut.thuooecr yaf)ESlA , o riD b tlmohla(eaohegtu EabdBPi cht lbua Rlsectnti) bilnl(uoohno k rirumbAta h Endl eirl tlini reta.

comments