wildfly jobss 同时连接多个数据源 datasource xa-datasource
由于需要从一个远程机器取数据。处理后保存到本地数据库处理。用 wildfly datasource 会报:
[com.arjuna.ats.arjuna] (default task-6) ARJUNA012140: Adding multiple last resources is disallowed. Trying to add LastResourceRecord(XAOnePhaseResource(LocalXAResourceImpl@7f19c56d[connectionListener=1......
这主要是jpa里面的的事物,只允许一个datasource连接。
采用xa-datasource即可。
另一种方案是在主控程序中禁止事务。将数据库的操作写在其他类中,使用事务。即只有要修改的操作才需要事务。
更一步,可以在远程取数据的类中,也是不需要事务的。这样就可以inject 需要使用事务的类。
主控类:
package com.italktv.iof.service; import java.util.List;
import java.util.logging.Logger; import javax.annotation.Resource;
import javax.ejb.Schedule;
import javax.ejb.Stateless;
import javax.ejb.Timer;
import javax.ejb.TimerService;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionManagement;
import javax.inject.Inject; import com.italktv.iof.entity.AccountInfoSync; @Stateless
@TransactionManagement(javax.ejb.TransactionManagementType.CONTAINER)
@TransactionAttribute(javax.ejb.TransactionAttributeType.NEVER)
public class SyncTableTimer { @Inject
private Logger logger; @Resource
private TimerService timerService; @Inject
IOFDbUtil iof; @Inject
private MySqlUtil mysql; // @Schedule(hour = "6", minute = "0", second = "0", persistent = false ,info = "6点执行 ")
@Schedule(hour = "*", minute = "*/1", second = "0", persistent = false, info = " ")
public void automaticCustomer() {
logger.info("=== job " + " started ====");
doTask();
logger.info("=== job end ====");
} private void cancelTimers() {
for (Timer timer : timerService.getTimers()) {
// timer.cancel();
}
} private void doTask() {
List<AccountInfoSync> list;
list = iof.getList();
while (list.size() > 0) {
logger.info(" list.size=" + list.size());
mysql.saveList(list);
list = iof.getList();
}
}
}
连接数据源1:
@Stateless
public class MySqlUtil { @Inject
private Logger logger; @PersistenceContext(unitName = "primary")
protected EntityManager em; public void saveList(List<AccountInfoSync> list) {
String dataSql = "select * " + "from profile where id=1";
Query nativeQuery = em.createNativeQuery(dataSql, MacProfile.class); MacProfile i;
try {
i = (MacProfile) nativeQuery.getSingleResult();
//
} catch (NoResultException e) {
i = new MacProfile();
} } }
连接数据源2,select操作
@Stateless
@TransactionManagement(javax.ejb.TransactionManagementType.CONTAINER)
@TransactionAttribute(javax.ejb.TransactionAttributeType.NEVER)
public class IOFDbUtil { @Inject
private Logger logger; @PersistenceContext(unitName = "theirDb")
private EntityManager theirDb; int FETCH_MAX_SIZE = 1;
int start = 0; @PostConstruct
void init() { } public List<AccountInfoSync> getList() { List<AccountInfoSync> list = null; while (true) {
String dataSql = "select * from dbtable "
+ "where id>" + start + " and id<=" + start + "+" + FETCH_MAX_SIZE;
Query nativeQuery = iof.createNativeQuery(dataSql, AccountInfoSync.class); list = (List<AccountInfoSync>) nativeQuery.getResultList();
start += FETCH_MAX_SIZE;
if (list.size() < 1 && start > maxid)
break; if (list.size() < 1) {
continue;
} for (AccountInfoSync iofsync : list) {
logger.info(iofsync.toString());
}
break;//找到就停止
}
return list;
} @Inject
MySqlUtil mm; private int getLastId() { mm.test();
return 0;
} }
- 使用xa-datasource解决方案
standardalone.xml中:
<subsystem xmlns="urn:jboss:domain:datasources:4.0">
<datasources>
<datasource jndi-name="java:jboss/datasources/ExampleDS" pool-name="ExampleDS" enabled="true" use-java-context="true">
<connection-url>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE</connection-url>
<driver>h2</driver>
<security>
<user-name>sa</user-name>
<password>sa</password>
</security>
</datasource>
<datasource jndi-name="java:jboss/datasources/MySqlDS" pool-name="MySqlDS" enabled="true" use-java-context="true">
<connection-url>jdbc:mysql://localhost:3306/statisticsystem</connection-url>
<driver>mysql</driver>
<security>
<user-name>jboss</user-name>
<password>jboss</password>
</security>
</datasource>
<datasource jndi-name="java:jboss/datasources/MySqlStatBank" pool-name="MySqlStatBank" enabled="true" use-java-context="true">
<connection-url>jdbc:mysql://211.100.75.204:5029/statistics</connection-url>
<driver>mysql</driver>
<security>
<user-name>root</user-name>
<password>@^#coopen</password>
</security>
</datasource>
<xa-datasource jndi-name="java:jboss/datasources/MySqlStatBank1" pool-name="MySqlStatBank1" enabled="true" use-java-context="true">
<xa-datasource-property name="ServerName">
211.100.75.204
</xa-datasource-property>
<xa-datasource-property name="PortNumber">
5029
</xa-datasource-property>
<xa-datasource-property name="DatabaseName">
statistics
</xa-datasource-property>
<driver>mysql</driver>
<xa-pool>
<min-pool-size>5</min-pool-size>
<initial-pool-size>5</initial-pool-size>
<max-pool-size>100</max-pool-size>
<prefill>true</prefill>
</xa-pool>
<security>
<user-name>root</user-name>
<password>@^#coopen</password>
</security>
</xa-datasource>
<drivers>
<driver name="h2" module="com.h2database.h2">
<xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>
</driver>
<driver name="mysql" module="com.mysqldatabase.mysql">
<driver-class>com.mysql.jdbc.Driver</driver-class>
<xa-datasource-class>com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</xa-datasource-class>
</driver>
</drivers>
</datasources>
</subsystem>
persistent.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
version="2.1"> <persistence-unit name="statLog">
<jta-data-source>java:jboss/datasources/MySqlStatBank1</jta-data-source>
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<!-- <class>com.italktv.colnv.stat.entity.LogOfPlay</class> -->
<!-- <class>com.italktv.colnv.stat.entity.LogOfView</class> --> <properties>
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
<!-- <property name= "hibernate.hbm2ddl.auto" value ="validate" /> create-drop -->
<property name="hibernate.jdbc.fetch_size" value="15" />
<property name="hibernate.jdbc.batch_size" value="10" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true"></property> <!--
<property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
<property name="javax.persistence.schema-generation-target" value="scripts"/>
<property name="javax.persistence.ddl-create-script-target" value="e:\createSeats.sql"/>
<property name="javax.persistence.ddl-drop-script-target" value="e:/dropSeats.sql"/>
-->
</properties> </persistence-unit> <persistence-unit name="primary" >
<class>com.italktv.colnv.stat.entity.Seat</class>
<class>com.italktv.colnv.stat.entity.SeatType</class>
<class>com.italktv.colnv.stat.entity.LogOfPlayDuration</class>
<class>com.italktv.colnv.stat.entity.ReportLiveHits</class> <properties>
<property name="hibernate.hbm2ddl.auto" value="update" />
<!-- <property name= "hibernate.hbm2ddl.auto" value ="validate" /> create-drop -->
<property name="hibernate.jdbc.fetch_size" value="15" />
<property name="hibernate.jdbc.batch_size" value="10" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true"></property> <!--
<property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
<property name="javax.persistence.schema-generation-target" value="scripts"/>
<property name="javax.persistence.ddl-create-script-target" value="e:\createSeats.sql"/>
<property name="javax.persistence.ddl-drop-script-target" value="e:/dropSeats.sql"/>
-->
</properties>
</persistence-unit> </persistence>
mysql driver的配置参考以前文档,在
<driver name="mysql" module="com.mysqldatabase.mysql"> 调用:
public class PlayDurationTask {
@PersistenceContext(unitName = "statLog")
private EntityManager emStatLog;
String query = "SELECT * FROM statistics.log_2016 ;";
List aa = emStatLog.createNativeQuery(query).getResultList();
//ddl语句用 createNativeUpdate
// 处理
for (int i = 0; i < aa.size(); i++) {
Object[] obj = (Object[]) aa.get(i);
// 使用obj[0],obj[1],obj[2]...取出属性
... ...
}
}
class two{
@PersistenceContext(unitName = "primary")
private EntityManager em ;
public void genLiveReport() {
em.createNativeQuery(LIVE_PLAY_USERS_BY_MAINID).executeUpdate();
logger.info(LIVE_PLAY_USERS_BY_MAINID);
}
参考:
Demystifying Datasource JTA and XA settings on JBoss-WildFly
One topic which is often misunderstood by middleware administrators is the configuration of JTA and XA attributesand their effect on transactions. Let's see more in practice.
Basically on a JBoss AS 6/WildFly configuration you can choose three different strategies as far as transactioons are concerned:
1) Setting jta = false and Non-XA datasource
|
1
|
<datasource jta="false" . . . > |
When setting this option you will be responsible for managing by yourself the transactions. For example, the following code will work when using a Datasource with JTA=false:
|
1
2
3
4
5
6
7
8
9
10
11
12
|
@Resource(mappedName="java:jboss/datasources/ExampleDS") private DataSource ds; . . . . . . . . . . .Connection conn = ds.getConnection();conn.setAutoCommit(false);PreparedStatement stmt = conn.prepareStatement("INSERT into PROPERTY values (?,?)");stmt.setString(1,key);stmt.setString(2,value);stmt.execute();conn.commit(); |
Please note: the datasource with jta=false corresponds exactly to the older definition of local-tx-datasource you can find in JBoss AS 4/5
What if you are using JPA instead ?
So, when using plain JDBC you can handle by yourself transaction boundaries using commit/rollback. What about if you are using JPA with JTA=false? in short, the transaction-type for JPA will be RESOURCE_LOCAL. This would use basic JDBC-level transactions. In such scenario you are responsible for EntityManager (PersistenceContext/Cache) creating and tracking and you have to follow these rules:
- You must use the EntityManagerFactory to get an EntityManager
- The resulting EntityManager instance is a PersistenceContext/Cache An EntityManagerFactory can be injected via the @PersistenceUnit annotation only (not @PersistenceContext)
- You are not allowed to use @PersistenceContext to refer to a unit of type RESOURCE_LOCAL
- You must use the EntityTransaction API to begin/commit around every call to your EntityManger
Here is an example of using JPA with a RESOURCE_LOCAL transaction:
|
1
2
3
4
5
6
7
|
@PersistenceUnit(unitName="unit01")private EntityManagerFactory emf; EntityManager em = emf.createEntityManager();em.getTransaction().begin();em.persist(mag);em.getTransaction().commit(); |
2) Setting jta = true and Non-XA datasource
|
1
|
<datasource jta="true" . . . > |
This is the default. When JTA is true, the JCA connection pool manager knows to enlist the connection into the JTA transaction. This means that, if the Driver and the database support it, you can use JTA transaction for a single resource.
|
1
2
3
4
5
6
|
@PersistenceContext(unitName = "unit01")private EntityManager entityManager;public void addMovie(Movie movie) throws Exception { entityManager.persist(movie);} |
If you try to manage JDBC transactions by yourself when jta=true an exception will be raised:
|
1
2
3
|
12:11:17,145 SEVERE [com.sample.Bean] (http-/127.0.0.1:8080-1) null: java.sql.SQLException: You cannot set autocommit during a managed transaction! at org.jboss.jca.adapters.jdbc.BaseWrapperManagedConnection.setJdbcAutoCommit(BaseWrapperManagedConnection.java:961) at org.jboss.jca.adapters.jdbc.WrappedConnection.setAutoCommit(WrappedConnection.java:716) |
3) Using an XA datasource
An XA transaction, in the most general terms, is a "global transaction" that may span multiple resources. A non-XA transaction always involves just one resource.
|
1
|
<xa-datasource . . . .> |
An XA transaction involves a coordinating transaction manager, with one or more databases (or other resources, like JMS) all involved in a single global transaction. Non-XA transactions have no transaction coordinator, and a single resource is doing all its transaction work itself.
The Transaction Manager coordinates all of this through a protocol called Two Phase Commit (2PC). This protocol also has to be supported by the individual resources.
In terms of datasources, an XA datasource is a data source that can participate in an XA global transaction. A non-XA datasource can't participate in a global transaction
wildfly jobss 同时连接多个数据源 datasource xa-datasource的更多相关文章
- wildfly jobss 同时连接多个数据源
由于需要从一个远程机器取数据.处理后保存到本地数据库处理.用 wildfly datasource 会报: [com.arjuna.ats.arjuna] (default task-6) ARJUN ...
- Netbeans 中创建数据连接池和数据源步骤(及解决无法ping通问题)
1.启动glassfish服务器, 在浏览器的地址栏中输入 http://localhost:4848 2.首先建立JDBC Connection Pools: 3.new 一个Connectio P ...
- jdbc基础 (五) 连接池与数据源 DBCP以及C3P0的使用
一.连接池的概念和使用 在实际应用开发中,特别是在WEB应用系统中,如果JSP.Servlet或EJB使用JDBC直接访问数据库中的数据,每一次数据访问请求都必须经历建立数据库连接.打开数据库.存取数 ...
- 在Tomcat中配置连接池和数据源
1.DataSource接口介绍 (1)DataSource 概述 JDBC1.0原来是用DriverManager类来产生一个对数据源的连接.JDBC2.0用一种替代的方法,使用DataSource ...
- spring boot 连接多个数据源
在springboot中有需要连接多个数据源的情况. 首先配置文件application.properties中添加两个数据源连接字符串 mybatis.type-aliases-package=co ...
- Spring学习11-Spring使用proxool连接池 管理数据源
Spring 一.Proxool连接池简介及其配置属性概述 Proxool是一种Java数据库连接池技术.是sourceforge下的一个开源项目,这个项目提供一个健壮.易用的连接池,最为关键的是 ...
- 连接池、数据源、JNDI三者间的关系及用法
连接池:连接池是由容器(比如Tomcat)提供的,用来管理池中的连接对象.连接池自动分配连接对象并对闲置的连接进行回收.连接池中的连接对象是由数据源(DataSource)创建的.连接池(Connec ...
- Spring使用proxool连接池 管理数据源
一.Proxool连接池简介及其配置属性概述 Proxool是一种Java数据库连接池技术.是sourceforge下的一个开源项目,这个项目提供一个健壮.易用的连接池,最为关键的是这个连接池提供监控 ...
- c3p0 连接池配置数据源
<!-- 配置数据源 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledD ...
随机推荐
- 介绍HTTP协议的传输过程
1.HTTP是面向事物的应用层协议,它使用TCP连接进行可靠传输,服务器默认监听在80端口 2.服务流程 从协议执行过程来说,当浏览器要访问www服务器时,首先要对服务器进行域名解析(DNS协议).一 ...
- 【亲测有效】Kali Linux无法安装网易云音乐的解决方案
问题描述 由于 Kali Linux 的内核是基于 Debian 的,我们在安装网易云音乐的时候更偏向于选择安装网易云音乐 v1.1.0 deepin15(64位) 的包,可是我发现在安装过程中,无法 ...
- 【CV】ICCV2015_Unsupervised Learning of Visual Representations using Videos
Unsupervised Learning of Visual Representations using Videos Note here: it's a learning note on Prof ...
- [BUAA软工]第1次阅读
[BUAA软工]第1次阅读 本次作业所属课程: 2019BUAA软件工程 本次作业要求: 第1次个人作业 我在本课程的目标 熟悉和实践软件工程流程,适应团队开发 本次作业的帮助 帮助理解<构建之 ...
- Linux内核分析第七周总结
第七章 可执行程序的装载 可执行程序的生成 可执行程序的生成: c语言代码--->经过编译器的预处理--->编译成汇编代码--->由汇编器编译成目标代码--->链接成可执行文件 ...
- 第七组团队项目——专业课程资源共享平台——需求分析&原型设计
一.项目目标.定位需求: (1)目标:在教师.学生之间建立一个综合的.全面的.快捷的.高效的免费课程和学习资源共享.交流与推荐的开放性平台,实现多维和动态的推荐与分类检索服务. (2)定位:学生与教师 ...
- 发布阶段 github和360移动助手及总结
经过一系列的冲刺和加工 最激动人心的无非在发布平台上公布上自己辛苦奋斗了一个周期的产品,这个时候的我们就像Iphone 6发布会上得CEO,为自己的产品完美画上了研发的句号. 接下来的日子就是准备ve ...
- .Net反编译软件
.Net反编译软件 https://www.cnblogs.com/xiandnc/p/10132491.html 一说起.net的反编译软件,大家首先想到的就是Reflector,ILSpy,dot ...
- “i词汇”宣传文案
目录 "i词汇"微信小程序 队名 :颜罗王team 成员: 姓名 学号 杨雪莹(PM) 201521123005 林楚虹 201521123002 董美凤 201521123003 ...
- Alpha冲刺随笔汇总
项目Alpha冲刺(团队) Alpha冲刺随笔汇总 姓名 学号 博客链接 何守成 031602408 http://www.cnblogs.com/heshoucheng/ 黄锦峰 031602411 ...