2011-01-25 26 views
6

Tôi đã nhận được một "API" dưới dạng một JAR để thực hiện một số hoạt động kế toán bên ngoài từ ứng dụng Java-Seam-Hibernate của tôi.Cách thực hiện giao dịch được quản lý theo cách thủ công

Nội bộ, API là một ứng dụng Hibernate đơn giản, sử dụng hai nguồn dữ liệu độc lập ngoài nguồn được sử dụng từ chính Seam.

Vấn đề là một trong những hoạt động "API" làm tăng ngoại lệ sau khi thực hiện một .commit nội bộ():

java.sql.SQLException: You cannot commit during a managed transaction! 
    at org.jboss.resource.adapter.jdbc.BaseWrapperManagedConnection.jdbcCommit(BaseWrapperManagedConnection.java:543) 
    at org.jboss.resource.adapter.jdbc.WrappedConnection.commit(WrappedConnection.java:334) 
    at org.hibernate.transaction.JDBCTransaction.commitAndResetAutoCommit(JDBCTransaction.java:139) 
    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:115) 
    at com.other.APIAccountingImpl.moneyMovement(APIAccountingImpl.java:261) 
    at com.myapp.integration.ExternalApiIntegrator.storeAcountingData(ExternalApiIntegrator.java:125) 
    at com.myapp.session.EmployeeAccounting.persistData(EmployeeAccounting.java:123) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
    at ... 

Mã nguồn của phương pháp moneyMovement trông giống như tiêu chuẩn Hibernate Session transaction idiom:

Session sess = factory.openSession(); 
Transaction tx; 
try { 
    tx = sess.beginTransaction(); 
    //do some work 
    ... 
    tx.commit(); 
} 
catch (Exception e) { 
    if (tx!=null) tx.rollback(); 
    throw e; 
} 
finally { 
    sess.close(); 
} 

Tôi đang sử dụng giao dịch được quản lý Seam với JTA. Tôi cũng buộc phải sử dụng API tùy chỉnh và tôi không được phép thay đổi mã nguồn.

Lựa chọn thay thế của tôi là gì? Làm thế nào tôi có thể cô lập các giao dịch quản lý Seam từ phiên "Hibernate" API? Có thể cấu hình kết nối từ một nguồn dữ liệu cụ thể để không phải là một trx được quản lý?

Trả lời

2

Có thể bạn đang sử dụng JTA, tiêu chuẩn Java EE để quản lý giao dịch. Trong trường hợp này, bạn đang sử dụng một giao dịch được quản lý. Nó có nghĩa là các container (JBoss, có vẻ như) là xử lý các ranh giới giao dịch, và sẽ sử dụng ngữ nghĩa JTA để rollback giao dịch trong trường hợp bạn ném một số ngoại lệ. Trong trường hợp này, bạn không xử lý trực tiếp giao dịch API. Bạn chỉ cần ném một số ngoại lệ trong trường hợp có điều gì đó sai xảy ra và nó sẽ đảm nhiệm việc quay lại các phần khác của giao dịch.

Điều đó nói rằng, tôi khuyên bạn nên xác nhận rằng JAR này bạn nhận được là api JTA. Nếu không, thì bạn chắc chắn sẽ cần tài liệu cho nó. Nếu có, bạn có thể sử dụng API giao dịch (và chú thích) để sử dụng phân định rõ ràng các giao dịch. (một số tài liệu có sẵn tại đây: http://download.oracle.com/javaee/5/tutorial/doc/bnciy.html#bnciz)

Nói chung, tôi thường khuyên bạn nên để container quản lý giao dịch của bạn, vì giao dịch thường trong ngữ cảnh của phương thức kinh doanh, có thể liên quan đến hai hoặc nhiều cuộc gọi DAO, do đó, tồn tại ngoài các giao dịch bạn có bên trong mỗi phương thức DAO.

0

Nếu bạn muốn 2 giao dịch được liên kết, bạn có thể ẩn với cấu hình ngủ đông để phiên bản giao dịch là phiên bản bạn kiểm soát. do đó bạn có thể cung cấp cho mã ngủ đông cơ bản một giao dịch giả mà không làm gì và để cho đường may kiểm soát giao dịch thực. Thay vào đó, nếu bạn không muốn 2 giao dịch được liên kết, bạn có thể gọi API từ phương thức ejb với thuộc tính giao dịch "không được hỗ trợ" (không phải siêu rõ ràng về cách Seam hoạt động, nhưng giả sử nó là ejb theo mui xe). điều này sẽ tách giao dịch API khỏi giao dịch Seam hiện tại.

Các vấn đề liên quan