Advertisement
Guest User

Untitled

a guest
Aug 19th, 2018
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.84 KB | None | 0 0
  1. package com.test.db;
  2.  
  3. import static org.junit.Assert.assertEquals;
  4.  
  5. import java.util.Date;
  6.  
  7. import javax.sql.DataSource;
  8.  
  9. import org.junit.Test;
  10. import org.junit.runner.RunWith;
  11. import org.springframework.beans.factory.annotation.Autowired;
  12. import org.springframework.beans.factory.annotation.Qualifier;
  13. import org.springframework.dao.DataIntegrityViolationException;
  14. import org.springframework.jdbc.core.JdbcTemplate;
  15. import org.springframework.test.context.ContextConfiguration;
  16. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
  17. import org.springframework.test.context.transaction.AfterTransaction;
  18. import org.springframework.test.context.transaction.BeforeTransaction;
  19. import org.springframework.transaction.annotation.Transactional;
  20.  
  21. //@EnableTransactionManagement
  22. @RunWith(SpringJUnit4ClassRunner.class)
  23. @ContextConfiguration(locations="/META-INF/spring/data-source-context.xml")
  24. public class MultipleDatasourceTests {
  25.  
  26. private JdbcTemplate jdbcTemplate;
  27. private JdbcTemplate otherJdbcTemplate;
  28.  
  29. @Autowired
  30. public void setDataSources(@Qualifier("dataSource") DataSource dataSource,
  31. @Qualifier("otherDataSource") DataSource otherDataSource) {
  32. this.jdbcTemplate = new JdbcTemplate(dataSource);
  33. this.otherJdbcTemplate = new JdbcTemplate(otherDataSource);
  34. }
  35.  
  36. @BeforeTransaction
  37. public void clearData() {
  38. jdbcTemplate.update("delete from T_ORACLE1");
  39. otherJdbcTemplate.update("delete from T_ORACLE1");
  40. }
  41.  
  42. @AfterTransaction
  43. public void checkPostConditions() {
  44.  
  45. int count = jdbcTemplate.queryForInt("select count(*) from T_ORACLE1");
  46. // This change was rolled back by the test framework
  47. assertEquals(0, count);
  48.  
  49. count = otherJdbcTemplate.queryForInt("select count(*) from T_ORACLE1");
  50. // This rolls back as well if the connections are managed together
  51. assertEquals(0, count);
  52.  
  53. }
  54.  
  55.  
  56. /**
  57. * Vanilla test case for two inserts into two data sources. Both should roll
  58. * back.
  59. *
  60. * @throws Exception
  61. */
  62. @Transactional
  63. @Test
  64. public void testInsertIntoTwoDataSources() throws Exception {
  65. jdbcTemplate.update("delete from T_ORACLE1");
  66. otherJdbcTemplate.update("delete from T_ORACLE2");
  67.  
  68. int count = jdbcTemplate.update(
  69. "INSERT into T_ORACLE1 (id,name,foo_date) values (?,?,null)", 0,
  70. "foo");
  71. assertEquals(1, count);
  72.  
  73. count = otherJdbcTemplate
  74. .update(
  75. "INSERT into T_ORACLE2 (id,operation,name,audit_date) values (?,?,?,?)",
  76. 1, "INSERT", "foo", new Date());
  77. assertEquals(1, count);
  78.  
  79. }
  80.  
  81. /**
  82. * Shows how to check the operation on the inner data source to see if it
  83. * has already been committed, and if it has do something different, instead
  84. * of just hitting a {@link DataIntegrityViolationException}.
  85. *
  86. * @throws Exception
  87. */
  88. @Transactional
  89. @Test
  90. public void testInsertWithCheckForDuplicates() throws Exception {
  91.  
  92.  
  93. int count = jdbcTemplate.update(
  94. "INSERT into T_ORACLE1 (id,name,foo_date) values (?,?,null)", 0,
  95. "foo");
  96. assertEquals(1, count);
  97.  
  98. count = otherJdbcTemplate.update(
  99. "UPDATE T_ORACLE2 set operation=?, name=?, audit_date=? where id=?",
  100. "UPDATE", "foo", new Date(), 0);
  101.  
  102. if (count == 0) {
  103. count = otherJdbcTemplate.update(
  104. "INSERT into T_ORACLE2 (id,operation,name,audit_date) values (?,?,?,?)",
  105. 0, "INSERT", "foo", new Date());
  106. }
  107.  
  108. assertEquals(1, count);
  109.  
  110. }
  111. }
  112.  
  113. <?xml version="1.0" encoding="UTF-8"?>
  114. <beans xmlns="http://www.springframework.org/schema/beans"
  115. xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  116. xmlns:context="http://www.springframework.org/schema/context"
  117. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
  118. http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
  119. http://www.springframework.org/schema/context
  120. http://www.springframework.org/schema/context/spring-context-2.5.xsd">
  121.  
  122. <context:annotation-config />
  123. <context:component-scan base-package="com.test.*"/>
  124.  
  125. <bean id="dataSource"
  126. class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  127. <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
  128. <property name="url" value="jdbc:oracle:thin:@//localhost:1521/TESTDB1" />
  129. <property name="username" value="ORACLE1"/>
  130. <property name="password" value="ORACLE1"/>
  131. </bean>
  132.  
  133. <bean id="otherDataSource"
  134. class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  135. <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
  136. <property name="url" value="jdbc:oracle:thin:@//localhost:1521/TESTDB2" />
  137. <property name="username" value="ORACLE2"/>
  138. <property name="password" value="ORACLE2"/>
  139. </bean>
  140.  
  141. <bean id="transactionManager" class="com.test.db.MultiTransactionManager">
  142. <property name="transactionManagers">
  143. <list>
  144. <bean
  145. class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  146. <property name="dataSource" ref="dataSource" />
  147. </bean>
  148. <bean
  149. class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  150. <property name="dataSource" ref="otherDataSource" />
  151. </bean>
  152. </list>
  153. </property>
  154. </bean>
  155.  
  156. </beans>
  157.  
  158.  
  159. package com.test.db;
  160.  
  161. import java.util.ArrayList;
  162. import java.util.Collections;
  163. import java.util.List;
  164.  
  165. import org.springframework.transaction.PlatformTransactionManager;
  166. import org.springframework.transaction.TransactionDefinition;
  167. import org.springframework.transaction.TransactionException;
  168. import org.springframework.transaction.TransactionStatus;
  169. import org.springframework.transaction.support.AbstractPlatformTransactionManager;
  170. import org.springframework.transaction.support.DefaultTransactionStatus;
  171.  
  172.  
  173. public class MultiTransactionManager extends
  174. AbstractPlatformTransactionManager {
  175.  
  176. private List<PlatformTransactionManager> transactionManagers = new ArrayList<PlatformTransactionManager>();
  177. private ArrayList<PlatformTransactionManager> reversed;
  178.  
  179. public void setTransactionManagers(
  180. List<PlatformTransactionManager> transactionManagers) {
  181. this.transactionManagers = transactionManagers;
  182. reversed = new ArrayList<PlatformTransactionManager>(
  183. transactionManagers);
  184. Collections.reverse(reversed);
  185. }
  186.  
  187. @Override
  188. protected void doBegin(Object transaction, TransactionDefinition definition)
  189. throws TransactionException {
  190. @SuppressWarnings("unchecked")
  191. List<DefaultTransactionStatus> list = (List<DefaultTransactionStatus>) transaction;
  192. for (PlatformTransactionManager transactionManager : transactionManagers) {
  193. DefaultTransactionStatus element = (DefaultTransactionStatus) transactionManager
  194. .getTransaction(definition);
  195. list.add(0, element);
  196. }
  197. }
  198.  
  199. @Override
  200. protected void doCommit(DefaultTransactionStatus status)
  201. throws TransactionException {
  202. @SuppressWarnings("unchecked")
  203. List<DefaultTransactionStatus> list = (List<DefaultTransactionStatus>) status
  204. .getTransaction();
  205. int i = 0;
  206. for (PlatformTransactionManager transactionManager : reversed) {
  207. TransactionStatus local = list.get(i++);
  208. try {
  209. transactionManager.commit(local);
  210. } catch (TransactionException e) {
  211. logger.error("Error in commit", e);
  212. // Rollback will ensue as long as rollbackOnCommitFailure=true
  213. throw e;
  214. }
  215. }
  216. }
  217.  
  218. @Override
  219. protected Object doGetTransaction() throws TransactionException {
  220. return new ArrayList<DefaultTransactionStatus>();
  221. }
  222.  
  223. @Override
  224. protected void doRollback(DefaultTransactionStatus status)
  225. throws TransactionException {
  226. @SuppressWarnings("unchecked")
  227. List<DefaultTransactionStatus> list = (List<DefaultTransactionStatus>) status
  228. .getTransaction();
  229. int i = 0;
  230. TransactionException lastException = null;
  231. for (PlatformTransactionManager transactionManager : reversed) {
  232. TransactionStatus local = list.get(i++);
  233. try {
  234. transactionManager.rollback(local);
  235. } catch (TransactionException e) {
  236. // Log exception and try to complete rollback
  237. lastException = e;
  238. logger.error("Error in rollback", e);
  239. }
  240. }
  241. if (lastException!=null) {
  242. throw lastException;
  243. }
  244. }
  245.  
  246. }
  247.  
  248. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  249. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  250. <modelVersion>4.0.0</modelVersion>
  251. <groupId>com.springsource.open</groupId>
  252. <artifactId>spring-best-db-db</artifactId>
  253. <version>2.0.0.CI-SNAPSHOT</version>
  254. <packaging>jar</packaging>
  255. <name>Spring Best Efforts DB-DB</name>
  256. <description><![CDATA[Sample project showing multi DataSource transaction
  257. processing with Spring using best efforts 1PC.
  258. ]]> </description>
  259. <properties>
  260. <maven.test.failure.ignore>true</maven.test.failure.ignore>
  261. <spring.framework.version>4.1.4.RELEASE</spring.framework.version>
  262. </properties>
  263. <profiles>
  264. <profile>
  265. <id>strict</id>
  266. <properties>
  267. <maven.test.failure.ignore>false</maven.test.failure.ignore>
  268. </properties>
  269. </profile>
  270. <profile>
  271. <id>fast</id>
  272. <properties>
  273. <maven.test.skip>true</maven.test.skip>
  274. </properties>
  275. </profile>
  276. </profiles>
  277. <dependencies>
  278. <dependency>
  279. <groupId>hsqldb</groupId>
  280. <artifactId>hsqldb</artifactId>
  281. <version>1.8.0.7</version>
  282. <scope>test</scope>
  283. </dependency>
  284. <dependency>
  285. <groupId>commons-io</groupId>
  286. <artifactId>commons-io</artifactId>
  287. <version>1.2</version>
  288. <scope>test</scope>
  289. </dependency>
  290. <dependency>
  291. <groupId>commons-logging</groupId>
  292. <artifactId>commons-logging</artifactId>
  293. <version>1.1</version>
  294. <exclusions>
  295. <exclusion>
  296. <groupId>avalon-framework</groupId>
  297. <artifactId>avalon-framework</artifactId>
  298. </exclusion>
  299. <exclusion>
  300. <groupId>logkit</groupId>
  301. <artifactId>logkit</artifactId>
  302. </exclusion>
  303. <exclusion>
  304. <groupId>javax.servlet</groupId>
  305. <artifactId>servlet-api</artifactId>
  306. </exclusion>
  307. </exclusions>
  308. </dependency>
  309. <dependency>
  310. <groupId>org.apache.derby</groupId>
  311. <artifactId>derby</artifactId>
  312. <version>10.2.1.6</version>
  313. <scope>test</scope>
  314. </dependency>
  315. <dependency>
  316. <groupId>junit</groupId>
  317. <artifactId>junit</artifactId>
  318. <version>4.9</version>
  319. <scope>test</scope>
  320. </dependency>
  321. <dependency>
  322. <groupId>org.easymock</groupId>
  323. <artifactId>easymock</artifactId>
  324. <version>2.4</version>
  325. <scope>test</scope>
  326. </dependency>
  327. <!-- Spring Dependencies -->
  328. <dependency>
  329. <groupId>org.springframework</groupId>
  330. <artifactId>spring-jdbc</artifactId>
  331. <version>${spring.framework.version}</version>
  332. </dependency>
  333. <dependency>
  334. <groupId>org.springframework</groupId>
  335. <artifactId>spring-test</artifactId>
  336. <version>${spring.framework.version}</version>
  337. <scope>test</scope>
  338. </dependency>
  339. <dependency>
  340. <groupId>org.springframework</groupId>
  341. <artifactId>spring-tx</artifactId>
  342. <version>${spring.framework.version}</version>
  343. </dependency>
  344. <dependency>
  345. <groupId>org.springframework</groupId>
  346. <artifactId>spring-aop</artifactId>
  347. <version>${spring.framework.version}</version>
  348. </dependency>
  349. <dependency>
  350. <groupId>org.springframework</groupId>
  351. <artifactId>spring-context</artifactId>
  352. <version>${spring.framework.version}</version>
  353. </dependency>
  354.  
  355. <dependency>
  356. <groupId>com.oracle</groupId>
  357. <artifactId>ojdbc8</artifactId>
  358. <version>12.1.0.1</version>
  359. </dependency>
  360. <!-- https://mvnrepository.com/artifact/com.github.marcus-nl.btm/btm-spring -->
  361. <dependency>
  362. <groupId>com.github.marcus-nl.btm</groupId>
  363. <artifactId>btm-spring</artifactId>
  364. <version>3.0.0-mk1</version>
  365. </dependency>
  366. <dependency>
  367. <groupId>javax</groupId>
  368. <artifactId>javaee-api</artifactId>
  369. <version>6.0</version>
  370. </dependency>
  371. </dependencies>
  372.  
  373. </project>
  374.  
  375. TABLE IN ORACLE1 database
  376. create table T_ORACLE1 (
  377. id integer not null primary key,
  378. name varchar(80),
  379. foo_date timestamp
  380. );
  381.  
  382. create table T_ORACLE2 (
  383. id integer not null primary key,
  384. operation varchar(20),
  385. name varchar(80),
  386. audit_date timestamp
  387. );
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement