2010-06-05 33 views
12

Tôi đã cập nhật tất cả các dịch vụ của mình để được giao dịch bằng cách sử dụng khả năng cuộn lại của Grail khi một RuntimeException được ném vào dịch vụ. Tôi có, trong hầu hết các trường hợp, thực hiện việc này:Quay lại giao dịch trong Dịch vụ Grails

def domain = new Domain(field: field) 
if (!domain.save()) { 
    throw new RuntimeException() 
} 

Dù sao, tôi muốn xác minh rằng điều này thực sự sẽ khôi phục giao dịch ... tôi nghĩ rằng liệu tại thời điểm này nó đã được cam kết. , nếu không, sẽ thiết lập tuôn ra: thay đổi thực sự đó? Tôi không quen thuộc với cách thức Spring/Hibernate thực hiện tất cả những điều này :)

Trả lời

15

Đúng là sẽ làm điều đó.

Giao dịch trong Grails theo mặc định được xử lý ở cấp Phương thức dịch vụ. Nếu phương thức trả về bình thường thì giao dịch sẽ được thực hiện, nếu một RuntimeException được ném, giao dịch sẽ được khôi phục.

Lưu ý điều này có nghĩa là ngay cả khi bạn sử dụng tuôn ra: đúng khi lưu đối tượng trong phương thức máy chủ, thay đổi db sẽ vẫn được khôi phục nếu bạn ném RuntimeException.

Ví dụ:

class MyService { 

def fiddle(id,id2){ 
    def domain = Domain.findById(id) 

    domain.stuff = "A change" 
    domain.save(flush:true) // will cause hibernate to perform the update statements 

    def otherDomain = OtherDomain.findById(id2)  

    otherDomain.name = "Fiddled" 

    if(!otherDomain.save(flush:true)){ // will also write to the db 
    // the transaction will be roled back 
    throw new RuntimeException("Panic what the hell happened") 
    }               
} 
} 

gì Tôi không phải 100% rõ ràng về với Grails là những gì sẽ xảy ra nếu một ngoại lệ kiểm tra được ném trong java thẳng/mùa xuân thế giới vi mặc định là cho inceptor giao dịch cam kết các giao dịch, althrough này có thể được overriden trong cấu hình.

Lưu ý: có báo trước và đó là db của bạn phải hỗ trợ các giao dịch trên các bảng bạn đang cập nhật. Có, điều này là poke tại MySQL :)

Điều này cũng áp dụng cho phương pháp Domain.withTransaction.

+0

Tuyệt vời, cảm ơn! – RyanLynch

+0

vui mừng được phục vụ –

+0

Ngoại lệ tùy chỉnh mở rộng RuntimeException phải OK, phải không? Ngoài ra, bạn có thể bật các giao dịch trong MySQL bằng cách cài đặt: phương ngữ = org.hibernate.dialect.MySQLInnoDBDialect trong dataSource :) – RyanLynch

2

Chỉ muốn thêm nhận xét bổ sung vào câu trả lời được chấp nhận và quá dài để vừa với nhận xét.

gì Tôi không phải 100% rõ ràng về với Grails là những gì sẽ xảy ra nếu một ngoại lệ kiểm tra được ném

Theo mặc định, ngoại trừ phải không được kiểm tra, hoặc các giao dịch sẽ không được triển khai trở lại. Rõ ràng đó là một điều Xuân.

Nếu bạn thực sự muốn kiểm tra ngoại lệ trên một phương pháp, bạn có thể đánh dấu rõ ràng phương thức dịch vụ là @Transactional và sử dụng đối số rollbackFor để liệt kê ngoại lệ nào vẫn nên gây ra khôi phục. (Lưu ý rằng tôi chưa thực sự thử nghiệm điều này.)

Lưu ý rằng, đánh dấu bất kỳ phương thức nào trong một dịch vụ với @Transactional sẽ tắt gói tự động của các phương thức khác bằng giao dịch. Vì vậy, nếu bạn làm điều đó cho một, bạn phải làm điều đó cho tất cả chúng. Hãy chắc chắn bạn thực sự cần để khai báo những ngoại lệ đã kiểm tra đó;)

Bạn có thể đọc thêm về điều này tại http://docs.grails.org/latest/guide/services.html.

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