Chúng tôi đang gặp phải lỗi Oracle Deadlock (org.hibernate.util.JDBCExceptionReporter - ORA-00060: bế tắc được phát hiện khi đang chờ tài nguyên). Nó đã được gợi ý rằng vấn đề là với một quá trình đó là thực hiện hoạt động chỉ đọc bằng cách sử dụng Hibernate trong khi một quá trình đang thực hiện một bản cập nhật trên cùng một hàng.Oracle Deadlock khi ứng dụng tải dữ liệu Hibernate để sử dụng chỉ đọc
Quy trình chỉ đọc được đề cập được định cấu hình bằng Hibernate và Spring. Chúng tôi chưa xác định rõ ràng giao dịch cho dịch vụ. Trong khi đó có thể không lý tưởng - Tôi không thấy tại sao Hibernate sẽ cố gắng để có được một khóa độc quyền trên một hàng khi không lưu/cập nhật các hoạt động đã được thực hiện - chỉ có được/tải. Vì vậy, câu hỏi của tôi là: Có Hibernate, khi không có quản lý giao dịch rõ ràng được xác định, cố gắng để có được một khóa đọc/ghi trên một hàng ngay cả khi chỉ có một "tải" của một đối tượng được thực hiện. Không Lưu/Cập nhật được thực hiện.
Có thể xác định giao dịch xung quanh dịch vụ đang tải dữ liệu và sau đó nói READONLY trên transactionAttributes sẽ khiến Hibernate bỏ qua một hàng khóa đã tồn tại và chỉ tải dữ liệu cho mục đích chỉ đọc?
Dưới đây là một số ví dụ mã:
Đối tải kỷ lục chúng tôi đang sử dụng một HibernateDaoTemplate
public class HibernatePurchaseOrderDataService extends HibernateDaoSupport implements PurchaseOrderDataService {
public PurchaseOrderData retrieveById(Long id) {
return (PurchaseOrderData)getHibernateTemplate().get(PurchaseOrderData.class, id);
}
}
Các cấu hình Spring cho dịch vụ gọi phương pháp này là:
<bean id="orderDataService"
class="com.example.orderdata.HibernatePurchaseOrderDataService">
<property name="sessionFactory" ref="orderDataSessionFactory"/>
</bean>
<bean id="orderDataSessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="hibernateDataSource"/>
<property name="hibernateProperties" ref="hibernateProperties"/>
<property name="mappingResources">
<list>
<value>com/example/orderdata/PurchaseOrderData.hbm.xml</value>
<value>com/example/orderdata/PurchaseOrderItem.hbm.xml</value>
</list>
</property>
</bean>
Các thực tế bế tắc đang xảy ra trên một trong các bản ghi PurchaseOrderItem đang được nạp bởi lệnh gọi nạp PurchaseOrder.
Điều này có gây ra bế tắc nếu bản ghi đang được tải đã bị khóa bởi một quy trình khác không? Và nếu vậy - sẽ thêm một trình bao bọc giao dịch như trình bao dưới đây giải quyết vấn đề?
<bean id="txWrappedOrderDataService"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="transactionManager"/>
<property name="target" ref="orderDataService"/>
<property name="transactionAttributes">
<props>
<!-- all methods require a transaction -->
<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
Cập nhật: Nhóm DataBase đã nhìn thấy quá trình "chỉ đọc" của chúng tôi thực sự ghi vào cơ sở dữ liệu tự động. Có các lệnh "UPDATE" đã đăng nhập được thực hiện trên các cột chính xác mà chúng ta đang đọc từ cơ sở dữ liệu. Dường như Hibernate tự động viết những bản ghi này trở lại cơ sở dữ liệu (mặc dù chúng tôi không yêu cầu nó). Điều đó có lẽ sẽ giải thích tại sao có bế tắc.
Điều này có thể là do phiên FLUSH hoặc điều gì đó tương tự không? Nhìn giống như giải pháp có thể là sử dụng trình bao bọc giao dịch với readOnly trên đó ...
Đây không phải là chính xác những gì đã xảy ra - nhưng có vẻ tương tự. Các giá trị không được "đặt" trong mã. Hibernate đã thực sự cố gắng để viết lại cùng một dữ liệu cho một số lý do (dữ liệu trong DB không bao giờ được cập nhật các giá trị khác nhau). – jonathanq