JavaEE5学习笔记01-JTA和数据库事务---1
?1.?????? 前言
JavaEE5的标准已经不是新鲜东西了,现在出了JavaEE6的标准,不过因为应用服务器像Weblogic和Websphere还没有大力支持呢,所以暂时先放放。
JavaEE5是以EJB3.0为核心内容所出的标准。
主要有:
Servlet2.5
JSP2.1
JSF1.2
JSTL1.2
JTA1.1
JPA2.0
EJB3.0
JMS1.1
JavaMail1.4
以上就是JavaEE5提出的相关标准
因为JPA在笔者的博客中单独有总结,在此系列不再做出总结,至于JSF等Web前端技术,之后会做一个文档形式的总结的。笔者是以Jboss5作为应用服务器(尽管JBoss6已经出了,并且支持JavaEE6标准),JDK版本是1.6.22,开发IDE为MyEclipse8.6.1。
2.?????? JTA简介
JTA(Java Transaction API)提供了事务划分接口标准,比如同一个数据库的事务,跨数据库访问业务的全局事务。在Java Web当中可能事务并不是十分重要(相对来说),而在JavaEE企业级开发,比如涉及到金额的电信、银行、商务等等对事务比较敏感的系统中,那么事务控制就是一个重点中的重点了。
JavaEE通常分为局部事务(Local Transaction Processing)和全局事务—istributed Transaction Processing)。如果业务是单一数据源就是用局部事务就可以了,如果需要多个数据源就需要全局事务来保证对外是透明的、就跟一个数据源没两样的策略。
3.?????? 简单的JTA例子
比如说我的数据库记录目前记录如下

?
Id是主键
之后我们在JBOSS中配置2个XA类型的数据源同时指向这一个数据库。

?
oracle1数据源配置内容如下
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<datasources>
??? <xa-datasource>
?????? ?<jndi-name>oracle1</jndi-name>
??????? <rar-name>jboss-xa-jdbc.rar</rar-name>
??????? <use-java-context>true</use-java-context>
??????? <connection-definition>javax.sql.DataSource</connection-definition>
??????? <jmx-invoker-name>jboss:service=invoker,type=jrmp</jmx-invoker-name>
??????? <min-pool-size>0</min-pool-size>
??????? <max-pool-size>10</max-pool-size>
??????? <blocking-timeout-millis>30000</blocking-timeout-millis>
??????? <idle-timeout-minutes>30</idle-timeout-minutes>
??????? <prefill>false</prefill>
??????? <background-validation>false</background-validation>
??????? <background-validation-millis>0</background-validation-millis>
??????? <validate-on-match>true</validate-on-match>
??????? <no-tx-separate-pools/>
??????? <statistics-formatter>org.jboss.resource.statistic.pool.JBossDefaultSubPoolStatisticFormatter</statistics-formatter>
??????? <isSameRM-override-value>false</isSameRM-override-value>
??????? <allocation-retry>0</allocation-retry>
??????? <allocation-retry-wait-millis>5000</allocation-retry-wait-millis>
??????? <application-managed-security xsi:type="securityMetaData" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
??????? <metadata>
??????????? <type-mapping>Oracle9i</type-mapping>
??????? </metadata>
??????? <type-mapping>Oracle9i</type-mapping>
??????? <user-name>system</user-name>
??????? <password>111111</password>
??????? <exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter</exception-sorter-class-name>
??????? <prepared-statement-cache-size>0</prepared-statement-cache-size>
??????? <share-prepared-statements>false</share-prepared-statements>
??????? <set-tx-query-timeout>false</set-tx-query-timeout>
??????? <query-timeout>0</query-timeout>
??????? <use-try-lock>60000</use-try-lock>
??????? <xa-datasource-class>oracle.jdbc.xa.client.OracleXADataSource</xa-datasource-class>
??????? <xa-datasource-property name="URL">jdbc:oracle:thin:@127.0.0.1:1521:jbossdemooracle</xa-datasource-property>
??????? <xa-resource-timeout>0</xa-resource-timeout>
??? </xa-datasource>
</datasources>
oracle2内容和它差不多,只是jndi-name不同而已。
下面是未加事务控制的测试代码
?????? try {
?????????? Context ctx = new InitialContext();
?????????? DataSource ds1 = (DataSource) ctx.lookup("java:/oracle1");
?????????? DataSource ds2 = (DataSource) ctx.lookup("java:/oracle2");
??????????
?????????? Connection connection1 = ds1.getConnection();
?????????? Connection connection2 = ds2.getConnection();
??????????
??????????
?????????? Statement statement1 = connection1.createStatement();
?????????? Statement statement2 = connection2.createStatement();
??????????
??????????
?????????? String sql1 = "insert into jimmy_user values(3,'青阳子')";
?????????? String sql2 = "insert into jimmy_user values(2,'非凡公子')";
??????????
??????????
?????????? int sun1 = statement1.executeUpdate(sql1);
?????????? int sun2 = statement2.executeUpdate(sql2);
??????????
??????????
?????????? statement1.close();
?????????? connection1.close();
??????????
?????????? statement2.close();
?????????? connection2.close();
?????? } catch (NamingException e) {
?????????? // TODO Auto-generated catch block
?????????? e.printStackTrace();
?????? } catch (SQLException e) {
?????????? // TODO Auto-generated catch block
?????????? e.printStackTrace();
?????? }
执行后看到数据库的结果如下:

?青阳子插进去了,非凡公子因为主键重复被甩了!