Skip to content

Commit

Permalink
Add DasTransactional.rollback and DasRunner (#24)
Browse files Browse the repository at this point in the history
* Add DasTransactional.rollback and DasRunner

* scope of junit dependency back to test

* Add testNestedTransaction and testNestedTransactionException in DasRunnerTest
  • Loading branch information
ShengyuanLu authored Jun 30, 2020
1 parent 86ba9e8 commit 7ac5831
Show file tree
Hide file tree
Showing 10 changed files with 245 additions and 56 deletions.
15 changes: 14 additions & 1 deletion das-client/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
<libthrift-version>0.12.0</libthrift-version>
<guava-version>23.0</guava-version>
<spring-version>4.3.8.RELEASE</spring-version>
<spring-boot-version>1.5.2.RELEASE</spring-boot-version>
<file_encoding>UTF-8</file_encoding>
</properties>
<dependencies>
Expand All @@ -40,7 +41,7 @@
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit-version}</version>
<scope>test</scope>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
Expand Down Expand Up @@ -115,6 +116,18 @@
<artifactId>guava</artifactId>
<version>${guava-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring-version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
<version>${spring-boot-version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<sourceDirectory>src/main/java</sourceDirectory>
Expand Down
9 changes: 9 additions & 0 deletions das-client/src/main/java/com/ppdai/das/client/Hints.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,15 @@ public Hints diagnose() {
return this;
}

public Hints rollbackOnly() {
set(HintEnum.rollbackOnly);
return this;
}

public boolean isRollbackOnly() {
return is(HintEnum.rollbackOnly);
}

/**
* Returns {@code DasDiagnose} instance.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,10 @@
* @return logic database name defined in dal.config/xml
*/
String logicDbName();

/**
*
* @return rollback transaction or not, default false
*/
boolean rollback() default false;
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@ public Object intercept(final Object obj, final Method method, final Object[] ar
}

final AtomicReference<Object> result = new AtomicReference<>();

if(getRollback(method)) {
hints.rollbackOnly();
}
DasClientFactory.getClient(getLogicDbName(method)).execute(() -> {
try {
result.set(proxy.invokeSuper(obj, args));
Expand All @@ -89,4 +91,13 @@ private String getLogicDbName(Method method) {

return method.getAnnotation(DasTransactional.class).logicDbName();
}

private boolean getRollback(Method method) {
DasTransactional tran = method.getAnnotation(DasTransactional.class);
if(tran != null) {
return tran.rollback();
}

return method.getAnnotation(DasTransactional.class).rollback();
}
}
7 changes: 6 additions & 1 deletion das-client/src/main/java/com/ppdai/das/core/HintEnum.java
Original file line number Diff line number Diff line change
Expand Up @@ -270,5 +270,10 @@ public enum HintEnum {
/**
* Columns to sort in-memory
*/
sortColumns
sortColumns,

/**
* Rollback transaction explicitly
*/
rollbackOnly
}
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,11 @@ public <T> T doInTransaction(ConnectionAction<T> action, Hints hints)throws SQLE

result = action.execute();

endTransaction(level);
if(hints.isRollbackOnly()) {
rollbackTransaction();
} else {
endTransaction(level);
}
} catch (Throwable e) {
action.error(e);
rollbackTransaction();
Expand Down
32 changes: 32 additions & 0 deletions das-client/src/main/java/com/ppdai/das/core/test/DasRunner.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.ppdai.das.core.test;

import com.ppdai.das.core.client.DalTransactionManager;
import org.junit.runners.model.InitializationError;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

/**
* Use this Runner to support declarative rollback in JUnit.
* The DasRunner is-a SpringJUnit4ClassRunner.
*
* sample:
* @Test
* @DasTransactional(logicDbName="MySqlSimple", rollback = true)
* public void test() throws SQLException {
* dao.insert(list);
* }
*
* @see {@link com.ppdai.das.client.annotation.DasTransactional}.
*/
public class DasRunner extends SpringJUnit4ClassRunner {
public DasRunner(Class<?> clazz) throws InitializationError {
super(clazz);
}

@Override
protected Object createTest() throws Exception {
Class clz = this.getTestClass().getJavaClass();
Object testInstance = DalTransactionManager.create(clz);
this.getTestContextManager().prepareTestInstance(testInstance);
return testInstance;
}
}
106 changes: 54 additions & 52 deletions das-client/src/test/java/com/ppdai/das/client/AllDasClientTests.java
Original file line number Diff line number Diff line change
@@ -1,52 +1,54 @@
package com.ppdai.das.client;

import com.ppdai.das.client.transaction.normal.BaseDalTransactionalAnnotationTest;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;

import com.ppdai.das.client.delegate.datasync.DataSyncConfigurationTest;
import com.ppdai.das.client.delegate.datasync.SequenceGeneratorTest;
import com.ppdai.das.client.sqlbuilder.AllSqlBuilderTests;
import com.ppdai.das.client.sqlbuilder.SqlBuilderSerializeTest;
import com.ppdai.das.configure.SlaveFreshnessScannerMysqlTest;
import com.ppdai.das.core.datasource.RefreshableDataSourceTest;
import com.ppdai.das.core.helper.ShardingManagerTest;
import com.ppdai.das.strategy.AllStrategyTests;
import com.ppdai.das.util.ConvertUtilsTest;

@RunWith(Suite.class)
@SuiteClasses({
AllSqlBuilderTests.class,
AllStrategyTests.class,
AllTableDaoTests.class,

BatchCallBuilderTest.class,
CallBuilderTest.class,

DasClientTest.class,
DasClientDBTest.class,
DasClientTableTest.class,
DasClientDbTableTest.class,
DasClientDbTableZeroTest.class,
DasClientDiagnoseTest.class,

SqlBuilderDBShardTest.class,
SqlBuilderTableShardTest.class,
SqlBuilderDbTableShardTest.class,

DistributedTransactionDbTest.class,
DistributedTransactionTableTest.class,
NestedTransactionTest.class,
BaseDalTransactionalAnnotationTest.class,

ConvertUtilsTest.class,
DataSyncConfigurationTest.class,
SequenceGeneratorTest.class,
ShardingManagerTest.class,
RefreshableDataSourceTest.class,
SqlBuilderSerializeTest.class,
SlaveFreshnessScannerMysqlTest.class,
})
public class AllDasClientTests {
}
package com.ppdai.das.client;

import com.ppdai.das.client.transaction.normal.BaseDalTransactionalAnnotationTest;
import com.ppdai.das.core.test.DasRunnerTest;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;

import com.ppdai.das.client.delegate.datasync.DataSyncConfigurationTest;
import com.ppdai.das.client.delegate.datasync.SequenceGeneratorTest;
import com.ppdai.das.client.sqlbuilder.AllSqlBuilderTests;
import com.ppdai.das.client.sqlbuilder.SqlBuilderSerializeTest;
import com.ppdai.das.configure.SlaveFreshnessScannerMysqlTest;
import com.ppdai.das.core.datasource.RefreshableDataSourceTest;
import com.ppdai.das.core.helper.ShardingManagerTest;
import com.ppdai.das.strategy.AllStrategyTests;
import com.ppdai.das.util.ConvertUtilsTest;

@RunWith(Suite.class)
@SuiteClasses({
AllSqlBuilderTests.class,
AllStrategyTests.class,
AllTableDaoTests.class,

BatchCallBuilderTest.class,
CallBuilderTest.class,

DasClientTest.class,
DasClientDBTest.class,
DasClientTableTest.class,
DasClientDbTableTest.class,
DasClientDbTableZeroTest.class,
DasClientDiagnoseTest.class,

SqlBuilderDBShardTest.class,
SqlBuilderTableShardTest.class,
SqlBuilderDbTableShardTest.class,

DasRunnerTest.class,
DistributedTransactionDbTest.class,
DistributedTransactionTableTest.class,
NestedTransactionTest.class,
BaseDalTransactionalAnnotationTest.class,

ConvertUtilsTest.class,
DataSyncConfigurationTest.class,
SequenceGeneratorTest.class,
ShardingManagerTest.class,
RefreshableDataSourceTest.class,
SqlBuilderSerializeTest.class,
SlaveFreshnessScannerMysqlTest.class,
})
public class AllDasClientTests {
}
31 changes: 31 additions & 0 deletions das-client/src/test/java/com/ppdai/das/core/test/DaoBean.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.ppdai.das.core.test;

import com.ppdai.das.client.DasClient;
import com.ppdai.das.client.DasClientFactory;
import com.ppdai.das.client.Person;
import com.ppdai.das.client.annotation.DasTransactional;
import org.springframework.stereotype.Component;

import java.sql.SQLException;

@Component
public class DaoBean {
private static final String DB_NAME = "MySqlSimple";

@DasTransactional(logicDbName = DB_NAME)
public void commitMethod() throws SQLException {
insert();
}

@DasTransactional(logicDbName = DB_NAME, rollback = true)
public void rollbackMethod() throws SQLException {
insert();
}

private void insert() throws SQLException {
DasClient dasClient = DasClientFactory.getClient(DB_NAME);
Person p = new Person();
p.setName("name");
dasClient.insert(p);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package com.ppdai.das.core.test;

import com.ppdai.das.client.DasClient;
import com.ppdai.das.client.DasClientFactory;
import com.ppdai.das.client.Person;
import com.ppdai.das.client.SqlBuilder;
import com.ppdai.das.client.annotation.DasTransactional;
import com.ppdai.das.client.transaction.DasTransactionalEnabler;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ContextConfiguration;

import java.sql.SQLException;

@RunWith(DasRunner.class)
@ContextConfiguration(classes = {DasTransactionalEnabler.class, DasRunnerTest.class, DaoBean.class})
@SpringBootTest
public class DasRunnerTest {

private static final String DB_NAME = "MySqlSimple";
private DasClient dasClient;
private boolean isRollback = false;
private long count = 0;

@Autowired
DaoBean daoBean;

@Before
public void before() throws SQLException {
dasClient = DasClientFactory.getClient(DB_NAME);
count = dasClient.queryObject(SqlBuilder.selectCount().from(Person.PERSON).intoObject());
}

@After
public void after() throws SQLException {
long now = dasClient.queryObject(SqlBuilder.selectCount().from(Person.PERSON).intoObject());
Assert.assertEquals(now, isRollback ? count : count + 1);
}

@Test
@DasTransactional(logicDbName = DB_NAME, rollback = true)
public void testRollback() throws SQLException {
isRollback = true;
Person p = new Person();
p.setName("name");
dasClient.insert(p);
}

@Test
@DasTransactional(logicDbName = DB_NAME)
public void testCommit() throws SQLException {
isRollback = false;
Person p = new Person();
p.setName("name");
dasClient.insert(p);
}

@Test
@DasTransactional(logicDbName = DB_NAME, rollback = true)
public void testNestedTransaction() throws SQLException {
isRollback = true;
daoBean.commitMethod();
}

@Test(expected = SQLException.class)
@DasTransactional(logicDbName = DB_NAME, rollback = false)
public void testNestedTransactionException() throws SQLException {
isRollback = true;
daoBean.rollbackMethod();
}
}

0 comments on commit 7ac5831

Please sign in to comment.