package com.taobao.tddl.matrix.test;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import com.taobao.tddl.common.exception.TddlException;
import com.taobao.tddl.executor.common.ExecutionContext;
import com.taobao.tddl.matrix.jdbc.TConnection;
import com.taobao.tddl.matrix.jdbc.TDataSource;
import com.taobao.tddl.repo.mysql.spi.My_Transaction;
public class TransactionTest {
static TDataSource ds = new TDataSource();
@BeforeClass
public static void initTestWithDS() throws TddlException, SQLException {
ds.setAppName("andor_show");
ds.setTopologyFile("test_matrix.xml");
ds.setSchemaFile("test_schema.xml");
ds.init();
}
@Test
public void testNotAutoCommit() throws Exception {
TConnection conn = (TConnection) ds.getConnection();
conn.setAutoCommit(false);
ExecutionContext context = conn.getExecutionContext();
Assert.assertTrue(context.getTransaction() == null);
{
PreparedStatement ps = conn.prepareStatement("select * from bmw_users where id=1");
ResultSet rs = ps.executeQuery();
rs.next();
rs.close();
}
Assert.assertTrue(context.getTransaction() != null);
My_Transaction t = (My_Transaction) context.getTransaction();
Assert.assertEquals("My_Transaction", t.getClass().getSimpleName());
Assert.assertEquals("andor_show_group1", context.getTransactionGroup());
Assert.assertEquals(1, t.getConnMap().size());
{
PreparedStatement ps = conn.prepareStatement("select * from bmw_users where id=1");
ResultSet rs = ps.executeQuery();
rs.next();
rs.close();
}
Assert.assertEquals(t, conn.getExecutionContext().getTransaction());
Assert.assertEquals(1, t.getConnMap().size());
conn.commit();
conn.close();
Assert.assertEquals(0, t.getConnMap().size());
}
@Test
public void testNotAutoCommitOnDifferentGroup() throws Exception {
TConnection conn = (TConnection) ds.getConnection();
conn.setAutoCommit(false);
ExecutionContext context = conn.getExecutionContext();
Assert.assertTrue(context.getTransaction() == null);
{
PreparedStatement ps = conn.prepareStatement("select * from bmw_users where id=1");
ResultSet rs = ps.executeQuery();
rs.next();
rs.close();
}
Assert.assertTrue(context.getTransaction() != null);
My_Transaction t = (My_Transaction) context.getTransaction();
Assert.assertEquals("My_Transaction", t.getClass().getSimpleName());
Assert.assertEquals("andor_show_group1", context.getTransactionGroup());
Assert.assertEquals(1, t.getConnMap().size());
{
try {
PreparedStatement ps = conn.prepareStatement("select * from bmw_users where id=2");
ResultSet rs = ps.executeQuery();
rs.next();
rs.close();
Assert.fail();
} catch (Exception ex) {
Assert.assertTrue(ex.getMessage().contains("transaction across group is not supported"));
}
}
Assert.assertEquals(context, conn.getExecutionContext());
Assert.assertEquals(t, conn.getExecutionContext().getTransaction());
Assert.assertEquals(1, t.getConnMap().size());
conn.commit();
conn.close();
Assert.assertEquals(0, t.getConnMap().size());
}
@Test
public void testAutoCommit() throws Exception {
TConnection conn = (TConnection) ds.getConnection();
conn.setAutoCommit(true);
ExecutionContext context = conn.getExecutionContext();
Assert.assertTrue(context.getTransaction() == null);
My_Transaction t1 = null;
{
PreparedStatement ps = conn.prepareStatement("select * from bmw_users where id=1");
ResultSet rs = ps.executeQuery();
rs.next();
context = conn.getExecutionContext();
Assert.assertTrue(context.getTransaction() != null);
t1 = (My_Transaction) context.getTransaction();
Assert.assertEquals("My_Transaction", t1.getClass().getSimpleName());
Assert.assertEquals("andor_show_group1", context.getTransactionGroup());
// autocommit, 事务链接不共享,单独管理
Assert.assertEquals(0, t1.getConnMap().size());
rs.close();
Assert.assertEquals(0, t1.getConnMap().size());
}
My_Transaction t2 = null;
{
PreparedStatement ps = conn.prepareStatement("select * from bmw_users where id=1");
ResultSet rs = ps.executeQuery();
context = conn.getExecutionContext();
rs.next();
t2 = (My_Transaction) context.getTransaction();
Assert.assertEquals(0, t2.getConnMap().size());
rs.close();
Assert.assertEquals(0, t2.getConnMap().size());
}
Assert.assertTrue(t1 != t2);
conn.commit();
conn.close();
Assert.assertEquals(0, t1.getConnMap().size());
Assert.assertEquals(0, t2.getConnMap().size());
}
/**
* 先做非auto的,再做auto的 两次的连接都应该被关闭
*
* @throws Exception
*/
@Test
public void testNotAutoCommit2() throws Exception {
TConnection conn = (TConnection) ds.getConnection();
conn.setAutoCommit(false);
ExecutionContext context1 = conn.getExecutionContext();
Assert.assertTrue(context1.getTransaction() == null);
{
PreparedStatement ps = conn.prepareStatement("select * from bmw_users where id=1");
ResultSet rs = ps.executeQuery();
Assert.assertEquals(context1, conn.getExecutionContext());
rs.next();
rs.close();
}
Assert.assertTrue(context1.getTransaction() != null);
My_Transaction t1 = (My_Transaction) context1.getTransaction();
Assert.assertEquals("My_Transaction", t1.getClass().getSimpleName());
Assert.assertEquals("andor_show_group1", context1.getTransactionGroup());
Assert.assertEquals(1, t1.getConnMap().size());
{
PreparedStatement ps = conn.prepareStatement("select * from bmw_users where id=1");
ResultSet rs = ps.executeQuery();
Assert.assertEquals(context1, conn.getExecutionContext());
rs.next();
rs.close();
}
Assert.assertEquals(t1, conn.getExecutionContext().getTransaction());
Assert.assertEquals(1, t1.getConnMap().size());
conn.commit();
// commit之后,事务就会关闭
Assert.assertEquals(0, t1.getConnMap().size());
conn.setAutoCommit(true);
{
PreparedStatement ps = conn.prepareStatement("select * from bmw_users where id=2");
ResultSet rs = ps.executeQuery();
rs.next();
rs.close();
}
ExecutionContext context2 = conn.getExecutionContext();
My_Transaction t2 = (My_Transaction) context2.getTransaction();
Assert.assertEquals("andor_show_group0", context2.getTransactionGroup());
Assert.assertTrue(context2 != context1);
conn.close();
Assert.assertEquals(0, t1.getConnMap().size());
Assert.assertEquals(0, t2.getConnMap().size());
}
}