扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
package jdbc;
import javax.sql.*;
import java.sql.*;
public class Bank
{
private DataSource dataSource;
public Bank() {}
public void setDataSource ( DataSource dataSource )
{
this.dataSource = dataSource;
}
private DataSource getDataSource()
{
return this.dataSource;
}
private Connection getConnection()
throws SQLException
{
Connection ret = null;
if ( getDataSource() != null ) {
ret = getDataSource().
getConnection();
}
return ret;
}
private void closeConnection ( Connection c )
throws SQLException
{
if ( c != null ) c.close();
}
public void checkTables()
throws SQLException
{
Connection conn = null;
try {
conn = getConnection();
Statement s = conn.createStatement();
try {
s.executeQuery (
"select * from Accounts" );
}
catch ( SQLException ex ) {
//table not there => create it
s.executeUpdate (
"create table Accounts ( " +
"account VARCHAR ( 20 ), " +
"owner VARCHAR(300), " +
"balance DECIMAL (19,0) )" );
for ( int i = 0; i < 100 ; i++ ){
s.executeUpdate (
"insert into Accounts values ( " +
"'account"+i +"' , 'owner"+i +"', 10000 )"
);
}
}
s.close();
}
finally {
closeConnection ( conn );
}
//That concludes setup
}
//
//Business methods are below
//
public long getBalance ( int account )
throws SQLException
{
long res = -1;
Connection conn = null;
try {
conn = getConnection();
Statement s = conn.createStatement();
String query =
"select balance from Accounts where account='"+
"account" + account +"'";
ResultSet rs = s.executeQuery ( query );
if ( rs == null || !rs.next() )
throw new SQLException (
"Account not found: " + account );
res = rs.getLong ( 1 );
s.close();
}
finally {
closeConnection ( conn );
}
return res;
}
public void withdraw ( int account , int amount )
throws Exception
{
Connection conn = null;
try {
conn = getConnection();
Statement s = conn.createStatement();
String sql =
"update Accounts set balance = balance - "+
amount + " where account ='account"+
account+"'";
s.executeUpdate ( sql );
s.close();
}
finally {
closeConnection ( conn );
}
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="datasource"
class="com.atomikos.jdbc.nonxa.NonXADataSourceBean">
<property name="user">
<value>sa</value>
</property>
<property name="url">
<value>jdbc:hsqldb:SpringNonXADB
</value>
</property>
<property name="driverClassName">
<value>org.hsqldb.jdbcDriver</value>
</property>
<property name="poolSize">
<value>1</value>
</property>
<property name="connectionTimeout">
<value>60</value>
</property>
</bean>
<bean id="bank" class="jdbc.Bank">
<property name="dataSource">
<ref bean="datasource"/>
</property>
</bean>
</beans>
package jdbc;
import com.atomikos.icatch.jta.UserTransactionImp;
import junit.framework.TestCase;
import java.io.FileInputStream;
import java.io.InputStream;
import org.springframework.beans.factory.xml.XmlBeanFactory;
public class BankTest extends TestCase
{
private UserTransactionImp utx;
private Bank bank;
public BankTest ( String name )
{
super ( name );
utx = new UserTransactionImp();
}
protected void setUp()
throws Exception
{
//start a new transaction
//so we can rollback the
//effects of each test
//in teardown!
utx.begin();
//open bean XML file
InputStream is =
new FileInputStream("config.xml");
//the factory is Spring's entry point
//for retrieving the configured
//objects from the XML file
XmlBeanFactory factory =
new XmlBeanFactory(is);
bank = ( Bank ) factory.getBean ( "bank" );
bank.checkTables();
}
protected void tearDown()
throws Exception
{
//rollback all DBMS effects
//of testing
utx.rollback();
}
public void testBank()
throws Exception
{
int accNo = 10;
long initialBalance = bank.getBalance ( accNo );
bank.withdraw ( accNo , 100 );
long newBalance = bank.getBalance ( accNo );
if ( ( initialBalance - newBalance ) != 100 )
fail ( "Wrong balance after withdraw: " +
newBalance );
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<!--
Use a JTA-aware DataSource
to access the DB transactionally
-->
<bean id="datasource"
class="com.atomikos.jdbc.nonxa.NonXADataSourceBean">
<property name="user">
<value>sa</value>
</property>
<property name="url">
<value>jdbc:hsqldb:SpringNonXADB</value>
</property>
<property name="driverClassName">
<value>org.hsqldb.jdbcDriver</value>
</property>
<property name="poolSize">
<value>1</value>
</property>
<property name="connectionTimeout">
<value>60</value>
</property>
</bean>
<!--
Construct a TransactionManager,
needed to configure Spring
-->
<bean id="jtaTransactionManager"
class="com.atomikos.icatch.jta.UserTransactionManager"/>
<!--
Also configure a UserTransaction,
needed to configure Spring
-->
<bean id="jtaUserTransaction"
class="com.atomikos.icatch.jta.UserTransactionImp"/>
<!--
Configure the Spring framework to use
JTA transactions from the JTA provider
-->
<bean id="springTransactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager">
<ref bean="jtaTransactionManager"/>
</property>
<property name="userTransaction">
<ref bean="jtaUserTransaction"/>
</property>
</bean>
<!-- Configure the bank to use our datasource -->
<bean id="bankTarget" class="jdbc.Bank">
<property name="dataSource">
<ref bean="datasource"/>
</property>
</bean>
<!--
Configure Spring to insert
JTA transaction logic for all methods
-->
<bean id="bank"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref bean="springTransactionManager"/>
</property>
<property name="target">
<ref bean="bankTarget"/>
</property>
<property name="transactionAttributes">
<props>
<prop key="*">
PROPAGATION_REQUIRED, -Exception
</prop>
</props>
</property>
</bean>
</beans>
package jms;
import jdbc.Bank;
import javax.jms.Message;
import javax.jms.MapMessage;
import javax.jms.MessageListener;
public class MessageDrivenBank
implements MessageListener
{
private Bank bank;
public void setBank ( Bank bank )
{
this.bank = bank;
}
//this method can be private
//since it is only needed within
//this class
private Bank getBank()
{
return this.bank;
}
public void onMessage ( Message msg )
{
try {
MapMessage m = ( MapMessage ) msg;
int account = m.getIntProperty ( "account" );
int amount = m.getIntProperty ( "amount" );
bank.withdraw ( account , amount );
System.out.println ( "Withdraw of " +
amount + " from account " + account );
}
catch ( Exception e ) {
e.printStackTrace();
//force rollback
throw new RuntimeException (
e.getMessage() );
}
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!--
NOTE: no explicit transaction manager bean
is necessary
because the QueueReceiverSessionPool will
start transactions by itself.
-->
<beans>
<bean id="datasource"
class="com.atomikos.jdbc.nonxa.NonXADataSourceBean">
<property name="user">
<value>sa</value>
</property>
<property name="url">
<value>jdbc:hsqldb:SpringNonXADB</value>
</property>
<property name="driverClassName">
<value>org.hsqldb.jdbcDriver</value>
</property>
<property name="poolSize">
<value>1</value>
</property>
<property name="connectionTimeout">
<value>60</value>
</property>
</bean>
<bean id="xaFactory"
class="org.activemq.ActiveMQXAConnectionFactory">
<property name="brokerURL">
<value>tcp://localhost:61616</value>
</property>
</bean>
<bean id="queue"
class="org.activemq.message.ActiveMQQueue">
<property name="physicalName">
<value>BANK_QUEUE</value>
</property>
</bean>
<bean id="bank" class="jdbc.Bank">
<property name="dataSource">
<ref bean="datasource"/>
</property>
</bean>
<bean id="messageDrivenBank"
class="jms.MessageDrivenBank">
<property name="bank">
<ref bean="bank"/>
</property>
</bean>
<bean id="queueConnectionFactoryBean"
class="com.atomikos.jms.QueueConnectionFactoryBean">
<property name="resourceName">
<value>QUEUE_BROKER</value>
</property>
<property name="xaQueueConnectionFactory">
<ref bean="xaFactory"/>
</property>
</bean>
<bean id="queueReceiverSessionPool"
class="com.atomikos.jms.QueueReceiverSessionPool"
init-method="start">
<property name="queueConnectionFactoryBean">
<ref bean="queueConnectionFactoryBean"/>
</property>
<property name="transactionTimeout">
<value>120</value>
</property>
<!--
default license allows only limited
concurrency so keep pool small
-->
<property name="poolSize">
<value>1</value>
</property>
<property name="queue">
<ref bean="queue"/>
</property>
<property name="messageListener">
<ref bean="messageDrivenBank"/>
</property>
</bean>
</beans>
package jms;
import java.io.FileInputStream;
import java.io.InputStream;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import com.atomikos.jms.QueueReceiverSessionPool;
import jdbc.Bank;
public class StartBank
{
public static void main ( String[] args )
throws Exception
{
//open bean XML file
InputStream is =
new FileInputStream(args[0]);
//the factory is Spring's entry point
//for retrieving the configured
//objects from the XML file
XmlBeanFactory factory =
new XmlBeanFactory(is);
//retrieve the bank to initialize
//alternatively, this could be done
//in the XML configuration too
Bank bank =
( Bank ) factory.getBean ( "bank" );
//initialize the bank if needed
bank.checkTables();
//retrieve the pool;
//this will also start the pool
//as specified in the beans XML file
//by the init-method attribute!
QueueReceiverSessionPool pool =
( QueueReceiverSessionPool )
factory.getBean (
"queueReceiverSessionPool" );
//Alternatively, start pool here
//(if not done in XML)
//pool.start();
System.out.println (
"Bank is listening for messages..." );
}
}
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者