2010-03-29 12 views
13

Chỉ cần tự hỏi nếu bắt đầu một giao dịch mới trong Hibernate thực sự phân bổ một kết nối đến DB?Có startTransaction trong Hibernate phân bổ một kết nối DB mới?

Tôi lo ngại b/c máy chủ của chúng tôi bắt đầu một giao dịch mới cho mỗi yêu cầu nhận được, ngay cả khi yêu cầu đó không tương tác với DB. Chúng tôi đang nhìn thấy các kết nối DB như một nút cổ chai lớn, vì vậy tôi tự hỏi nếu tôi nên dành thời gian thu hẹp phạm vi giao dịch của tôi.

Tìm kiếm ở khắp mọi nơi và không thể tìm thấy câu trả lời hay. Mã rất đơn giản là ở đây:

SessionFactory sessionFactory = (SessionFactory) Context.getContext().getBean("sessionFactory"); 
    sessionFactory.getCurrentSession().beginTransaction(); 
    sessionFactory.getCurrentSession().setFlushMode(FlushMode.AUTO); 

cảm ơn rất nhiều! một

Trả lời

8

(Cập nhật mỗi comment Pascal Thivent của)

Mỗi Session tạo ra một kết nối cơ sở dữ liệu nếu có một nhu cầu cho điều đó - ví dụ nếu một giao dịch được bắt đầu. Kết nối không được mở ra chỉ với việc tạo phiên.

Để khắc phục điều này, bạn có thể sử dụng connecetion pool để kết nối được sử dụng lại. Hoặc bạn có thể chắc chắn (như nó xuất hiện bạn đã làm) mà không có giao dịch được bắt đầu tự động.

(This thảo luận về giao dịch chỉ đọc Hãy xem..)

+0

Cảm ơn, chúng tôi đang sử dụng hồ bơi kết nối. Bằng cách không bắt đầu một giao dịch theo mặc định, chúng tôi đã có thể giảm tải một cách ồ ạt trên cơ sở dữ liệu của chúng tôi. – illscience

+1

Trên thực tế, kết nối được tải trong một phiên 'lười biếng '. Xem câu trả lời của tôi để biết chi tiết. –

+0

@Pascal Thivent hm, thú vị và hợp lý :) @illscience vui lòng thay đổi câu trả lời được chấp nhận – Bozho

14

Theo phần 11.1. Session and transaction scopes của tài liệu Hibernate:

Một SessionFactory là một đắt-to-tạo, threadsafe đối tượng, dự định được chia sẻ bởi tất cả các chủ đề ứng dụng . Nó được tạo ra một lần, thường là khi khởi động ứng dụng, từ một ví dụ Configuration.

Một Session là một, đối tượng phi threadsafe rẻ tiền nên được sử dụng một lần và sau đó bỏ đi cho: a yêu cầu duy nhất, một cuộc trò chuyện hoặc một đơn vị duy nhất công việc. A Session sẽ không nhận được JDBC Connection hoặc Datasource, trừ khi cần. Nó sẽ không tiêu thụ bất kỳ tài nguyên nào cho đến khi sử dụng .

Để giảm tranh chấp khóa trong cơ sở dữ liệu , giao dịch cơ sở dữ liệu phải càng ngắn càng tốt. Các giao dịch cơ sở dữ liệu dài sẽ ngăn không cho ứng dụng của bạn mở rộng thành một tải trọng cao đồng thời . Không phải là đề nghị bạn giữ cơ sở dữ liệu giao dịch mở trong khi người dùng nghĩ rằng thời gian cho đến khi đơn vị công việc hoàn tất .

Bây giờ, để trả lời câu hỏi của bạn:

  • nhận được một Session không không ngay lập tức có được một kết nối (kết nối được lười biếng nạp)
  • nhưng gọi beginTransaction() sẽ gây ra tải trọng của kết nối cho Session
  • các cuộc gọi tiếp theo sẽ sử dụng lại cùng một số connection

Nhìn vào số org.hibernate.impl.SessionImpl#beginTransaction() và xem mã để biết thêm chi tiết.

+0

+1, tất nhiên (15chrs) – Bozho

+0

@Bozho Cảm ơn! –

+0

THanks. Câu trả lời hay –

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