![](/img/trans.png)
[英]Spring @Transaction(readOnly = true) propagation to threads
[英]Java: XA Transaction propagation within many threads
如何在Java SE(非Java EE或Spring)中使用事務管理器(如Bitronix , JBoss TS或Atomikos )來支持以下用例:
我們假設我們有以下類:
public class Dao {
public void updateDatabase(DB db) {
connet to db
run a sql
}
}
我們從中創建一個Java Runnable,如下所示:
public class MyRunnable extends Runnable {
Dao dao;
DB db;
public MyRunnable(Dao dao, DB db) {
this.dao=dao;
this.db = db;
}
public run() throws Exception {
return dao.updateDatabase(db);
}
}
現在在我們的服務層,我們有另一個類:
public class Service {
public void updateDatabases() {
BEGIN TRANSACTION;
ExecutorService es = Executors.newFixedThreadPool(10);
ExecutorCompletionService ecs = new ExecutorCompletionService(es);
List<Future<T>> futures = new ArrayList<Future<T>>(n);
Dao dao = new Dao();
futures.add(ecs.submit(new MyRunnable(dao, new DB("db1")));
futures.add(ecs.submit(new MyRunnable(dao, new DB("db2")));
futures.add(ecs.submit(new MyRunnable(dao, new DB("db3")));
for (int i = 0; i < n; ++i) {
completionService.take().get();
}
END TRANSACTION;
}
}
客戶端可以是Servlet或任何其他多線程環境:
public MyServlet extend HttpServlet {
protected void service(final HttpServletRequest request, final HttpServletResponse response) throws IOException {
Service service = new Service();
service.updateDatabases();
}
}
BEGIN TRANSACTION和END TRANSACTION部分的正確代碼是什么? 這甚至可行嗎? 如果沒有,需要改變什么? 要求是使updateDatabases()方法保持並發(因為它將同時訪問多個數據庫)和事務性。
這似乎可以使用SubTxThread使用Atomikos完成
//first start a tx
TransactionManager tm = ...
tm.begin();
Waiter waiter = new Waiter();
//the code that calls the first EIS; defined by you
SubTxCode code1 = ...
//the associated thread
SubTxThread thread1 = new SubTxThread ( waiter , code1 );
//the code that calls the second EIS; defined by you
SubTxCode code2 = ...
//the associated thread
SubTxThread thread2 = new SubTxThread ( waiter , code2 );
//start each thread
thread1.start();
thread2.start();
//wait for completion of all calls
waiter.waitForAll();
//check result
if ( waiter.getAbortCount() == 0 ) {
//no failures -> commit tx
tm.commit();
} else {
tm.rollback();
}
XA規范要求所有XA調用都在同一個線程上下文中執行。 詳細說明其原因,因為可以在任何事務分支甚至在線程中創建之前調用提交。
如果您只對如何在JBoss TS中的XA事務中執行這三個調用感興趣
首先確保您的-ds.xml
將數據源指定為<xa-datasource>
InitialContext ctx = new InitialContext(parms);
UserTransaction ut = (UserTransaction) ctx.lookup("java:comp/UserTransaction");
ut.begin();
//Some Transactional Code
ut.commit();
請記住上面的代碼,您將無法使用ExecutorService來並行化調用。
旁注:我不太了解它,但JTS / OTS聲稱允許多個線程在事務中共享。 我認為它是通過傳播類似於ws-coordination / ws-transaction的事務上下文來實現的,並且得到了JBossTS的支持。 可能是一個紅鯡魚,但如果你沒有時間緊縮,它可能值得研究。
你呢
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.