Package org.nutz.trans

Source Code of org.nutz.trans.TransactionTest$Bomb

package org.nutz.trans;

import static org.junit.Assert.*;

import org.junit.Test;

import org.nutz.dao.test.DaoCase;
import org.nutz.lang.Lang;
import org.nutz.service.IdEntityService;
import org.nutz.trans.Atom;
import org.nutz.trans.Trans;

public class TransactionTest extends DaoCase {

    private IdEntityService<Cat> catService;
    private IdEntityService<Company> comService;
    private IdEntityService<Master> masterService;

    protected void before() {
        dao.create(Company.class, true);
        dao.create(Master.class, true);
        dao.create(Cat.class, true);
        catService = new IdEntityService<Cat>(dao) {};
        comService = new IdEntityService<Company>(dao) {};
        masterService = new IdEntityService<Master>(dao) {};
    }

    protected void after() {}

    private Cat insert(final Cat cat, final Bomb bomb) {
        // //System.out.printf("\n>> insert cat: %d\n",
        // bomb.times);
        Trans.exec(new Atom() {
            public void run() {
                dao.insert(cat);
                cat.setMaster(insert(cat.getMaster(), bomb));
                bomb.bong();
            }
        });
        // //System.out.printf("<< insert cat: %d\n",
        // bomb.times);
        return cat;
    }

    private Company insert(final Company com, final Bomb bomb) {
        // //System.out.printf("\n>> insert company: %d\n",
        // bomb.times);
        Trans.exec(new Atom() {
            public void run() {
                dao.insert(com);
                bomb.bong();
            }
        });
        // //System.out.printf("<< insert company: %d\n",
        // bomb.times);
        return com;
    }

    private Master insert(final Master master, final Bomb bomb) {
        // //System.out.printf("\n>> insert master: %d\n",
        // bomb.times);
        Trans.exec(new Atom() {
            public void run() {
                dao.insert(master);
                master.setCom(insert(master.getCom(), bomb));
                bomb.bong();
            }
        });
        // //System.out.printf("<< insert master: %d\n",
        // bomb.times);
        return master;
    }

    private static class Bomb {

        private int times;

        Bomb(int times) {
            this.times = times;
        }

        Bomb bong() throws RuntimeException {
            if (--times == 0) {
                // //System.out.printf("Bong!!! bomb-- %d => %d\n",
                // times + 1,
                // times);
                throw new RuntimeException("Bong!!!");
            }
            // //System.out.printf("bomb-- %d => %d\n",
            // times + 1, times);
            return this;
        }
    }

    @Test
    public void testNestedCommit() {
        Cat cat = Cat.create("XiaoBai", Master.create("zzh", Company.create("Dtri")));
        insert(cat, new Bomb(-1));
        assertEquals(1, dao.count(Cat.class));
        assertEquals(1, dao.count(Master.class));
        assertEquals(1, dao.count(Company.class));
        assertNull(Trans.get());
        assertEquals(0, Trans.count.get().intValue());
    }

    @Test
    public void testNestedRollback() {
        Cat cat = Cat.create("XiaoBai", Master.create("zzh", Company.create("Dtri")));
        try {
            insert(cat, new Bomb(2));
            fail();
        }
        catch (Exception e) {
            assertEquals(0, dao.count(Company.class));
            assertEquals(0, dao.count(Master.class));
            assertEquals(0, dao.count(Cat.class));
            assertNull(Trans.get());
        }
    }

    class CheckCheck extends Thread {

        private Object lock = new Object();
        private Object tellor;
        private boolean standby;

        public boolean isStandby() {
            return standby;
        }

        public void run() {
            // System.out.println("\nI am checker");
            try {
                synchronized (lock) {
                    standby = true;
                    // System.out.println("\nchecker: I am standby and wait for another thread...");
                    lock.wait();
                    // System.out.println("\nchecker: I will do some check");
                }
                if (0 != dao.count(Company.class, null)
                    || 0 != dao.count(Master.class, null)
                    || 0 != dao.count(Cat.class, null)) {
                    throw new RuntimeException("Find change in another thread");
                }
            }
            catch (InterruptedException e) {
                throw Lang.wrapThrow(e);
            }
            finally {
                synchronized (tellor) {
                    // System.out.println("\nchecker: I will notify tellor!");
                    tellor.notifyAll();
                    // System.out.println("\nchecker: I done for notify tellor");
                }
            }
        }
    }

    class AnotherThread extends Thread {
        private Object checker;
        private Object tellor;
        public Object waiter;

        public void run() {
            Trans.exec(new Atom() {
                public void run() {
                    // System.out.println("\nI am another");
                    Company com = Company.create("dtri");
                    Master m = Master.create("zzh", com);
                    Cat c1 = Cat.create("XiaoBai", m);
                    Cat c2 = Cat.create("Tony", m);

                    comService.dao().insert(com);
                    assertEquals(1, dao.count(Company.class, null));
                    m.setComId(com.getId());
                    masterService.dao().insert(m);
                    assertEquals(1, dao.count(Master.class, null));
                    c1.setMasterId(m.getId());
                    c2.setMasterId(m.getId());
                    catService.dao().insert(c1);
                    catService.dao().insert(c2);
                    assertEquals(2, dao.count(Cat.class, null));
                    synchronized (checker) {
                        // System.out.println("\nanother: finished to myjob and I will tell checker...");
                        checker.notifyAll();
                        // System.out.println("\nanother: I done for notify checker");
                    }
                    try {
                        synchronized (tellor) {
                            // System.out.println("\nanother: I will wait 100 ms");
                            tellor.wait(100);
                            // System.out.println("\nanother: I am wake up");
                        }
                    }
                    catch (InterruptedException e) {
                        throw Lang.wrapThrow(e);
                    }
                }
            });
            // System.out.println("\nanother: I will tell waiter");
            synchronized (waiter) {
                waiter.notifyAll();
            }
            // System.out.println("\nanother: done for tell waiter");
        }

    }

    @Test
    public void testRollback() {
        // In transaction
        try {
            Trans.exec(new Atom() {
                public void run() {
                    Company com = Company.create("dtri");
                    Master m = Master.create("zzh", com);
                    Cat c1 = Cat.create("XiaoBai", m);
                    Cat c2 = Cat.create("Tony", m);

                    comService.dao().insert(com);
                    assertEquals(1, dao.count(Company.class, null));
                    m.setComId(com.getId());
                    masterService.dao().insert(m);
                    assertEquals(1, dao.count(Master.class, null));
                    c1.setMasterId(m.getId());
                    c2.setMasterId(m.getId());
                    catService.dao().insert(c1);
                    catService.dao().insert(c2);
                    assertEquals(2, dao.count(Cat.class, null));
                    throw new RuntimeException("Stop!!!");
                }
            });
            fail();
        }
        catch (Exception e) {
            assertEquals(0, dao.count(Company.class, null));
            assertEquals(0, dao.count(Master.class, null));
            assertEquals(0, dao.count(Cat.class, null));
            assertEquals(0, Trans.count.get().intValue());
            assertNull(Trans.get());
        }
    }
}
TOP

Related Classes of org.nutz.trans.TransactionTest$Bomb

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.
ga('send', 'pageview');