được sửa đổi:
Vâng, SQLite doesn't support giao dịch lồng nhau, nhưng docs tuyên bố rằng SQLiteDatabase làm.
Tình huống
Tôi có phương thức chứa giao dịch và tôi cần gọi phương thức này từ giao dịch khác.
Ngoài ra - cả hai giao dịch đều hoạt động trên cùng một bộ hồ sơ, nhưng cập nhật các cột khác nhau.
Vấn đề
Có vẻ như kết quả của các giao dịch bên ngoài của tôi bị hủy bởi bên trong, cả hai đều được đánh dấu sạch sẽ bằng setTransactionSuccessful() và kết thúc bằng endTransaction() - Tôi đã kiểm tra điều này.
Câu hỏi
- Bất kỳ ý tưởng nào tại sao điều này có thể xảy ra?
- Có cách nào được khuyến nghị để thực hiện các giao dịch như vậy không?SQLiteDatabase giao dịch lồng nhau và workaround
Trả lời
Bạn có thể giao dịch tổ với các API sqlite Android, với caveats:
giao dịch có thể được lồng vào nhau. Khi giao dịch bên ngoài kết thúc tất cả công việc được thực hiện trong giao dịch đó và tất cả các giao dịch lồng nhau sẽ được cam kết hoặc quay trở lại. Các thay đổi sẽ được khôi phục nếu bất kỳ giao dịch nào kết thúc mà không được đánh dấu là sạch (bằng cách gọi setTransactionSuccessful). Nếu không, họ sẽ được cam kết.
Cách tiếp cận khác mà tôi thấy được sử dụng với sqlite nói chung là chuyển một tham số boolean isInTransaction
cho biết phương thức được gọi là tự xử lý giao dịch hoặc cho người gọi xử lý giao dịch.
"Giao dịch Android lồng nhau" làm không sử dụng SQLites lồng nhau giao dịch/điểm hỗ trợ.
Thay vì giao dịch Android lồng nhau ngăn chặn biểu hiện giao dịch SQLite. Giao dịch lồng nhau không thể tự động khôi phục vì nó không tồn tại ngoài giao dịch bên ngoài. Điều này có thể be seen here với bảo vệ mTransactionStack == null
.
Cách duy nhất để thực sự hỗ trợ lồng giao dịch - mà SQLite không hỗ trợ, chỉ cần không phải với BEGIN/COMMIT - là để tự sử dụng các lệnh savepoint/RELEASE. Tất nhiên, việc thiết kế mã để không dựa vào điều này sẽ loại bỏ việc quản lý thủ công bổ sung mà điều này đòi hỏi.
(Tôi có lẽ sẽ di chuyển tất cả các công việc giao dịch ra khỏi các hoạt động cá nhân thực tế, để lại công tác quản lý để người gọi cấp cao;. Làm việc này khá tốt cho một mẫu UOW, nhưng có thể không phải lúc nào được áp dụng)
Bây giờ tôi đã kết thúc với thiết kế phương pháp đối xứng (tương tự như đề xuất laalto) cung cấp công việc chính xác. Đó là một cách giải quyết rõ ràng "chuyển đổi" các giao dịch lồng nhau thành một giao dịch duy nhất.
Bây giờ tôi có thể gọi riêng cho họ hoặc từ người khác (không có phản ứng phụ mà tôi vẫn không hiểu).
Ở đây là:
public void method1() {
SQLiteDatabase db = dbhelper.getWritableDatabase();
boolean doAsTransaction = !db.inTransaction();
if (doAsTransaction)
db.beginTransaction();
try {
// ...
if (doAsTransaction)
db.setTransactionSuccessful();
} catch (Exception e) {
// ...
} finally {
// ...
if (doAsTransaction)
db.endTransaction();
}
}
public void method2() {
SQLiteDatabase db = dbhelper.getWritableDatabase();
boolean doAsTransaction = !db.inTransaction();
if (doAsTransaction)
db.beginTransaction();
try {
// ...
method1();
if (doAsTransaction)
db.setTransactionSuccessful();
} catch (Exception e) {
// ...
} finally {
// ...
if (doAsTransaction)
db.endTransaction();
}
}
Bạn có thể thực hiện giao dịch lồng nhau bằng cách sử dụng SQL liệu cho savepoints trong execSQL()
theo cách này:
db.execSql("SAVEPOINT test"); // declare savepoint
// ... do some operations
db.execSql(";ROLLBACK TO test"); // rollback
db.execSql("RELEASE test"); // save changes
chấm phẩy trước mặt ROLLBACK là cần thiết, bởi vì không có nó cơ sở dữ liệu Android khung sẽ cố gắng gọi endTransaction()
. Xem mã của các phương thức android.database.sqlite.SQLiteSession#executeSpecial
và android.database.sqlite.SQLiteSession#execute
để biết chi tiết.
- 1. giao dịch lồng nhau trong SQL Server
- 2. Giao dịch lồng nhau trong postgresql 8.2?
- 3. giao dịch lồng nhau với TransactionScope
- 4. Các giao dịch lồng nhau trong TSQL
- 5. Giao dịch lồng nhau sử dụng Spring và Hibernate
- 6. Mục đích của các giao dịch lồng nhau
- 7. Cách sửa cấu trúc lồng nhau trong giao dịch bookshelfjs
- 8. SQL SERVER 2008R2 Giao dịch lồng nhau với RAISERROR
- 9. Số giao dịch lồng nhau và/hoặc kết nối lồng nhau gây ra sự gia tăng MSDTC
- 10. Lớp lồng nhau bên trong giao diện
- 11. Làm cách nào để bật các giao dịch lồng nhau với ADO.NET và SQL Server?
- 12. Thực hiện giao diện chung lồng nhau
- 13. Đối số lồng nhau không biên dịch
- 14. Biên dịch tràn bộ nhớ C# compiler (csc.exe) biên soạn các kiểu lồng nhau và Linq
- 15. Cách quay trở lại các giao dịch lồng nhau lưu trữ bằng Hibernate
- 16. Làm cách nào để tránh lỗi giao dịch lồng nhau không được hỗ trợ?
- 17. Rails 5 ActionView :: Template :: Lỗi xảy ra trong controller # action: "giao dịch lồng nhau"
- 18. Cách sử dụng lồng ghép giao dịch lồng nhau đối với cơ sở dữ liệu SQL Azure
- 19. giao thức Swift lồng nhau trong một lớp học
- 20. Các giao dịch lồng nhau có được phép trong MySQL không?
- 21. Làm cách nào để đảm bảo rằng các giao dịch lồng nhau được cam kết độc lập với nhau?
- 22. Lớp bên trong và lồng nhau Java
- 23. Giao tiếp giữa các chỉ thị lồng nhau
- 24. $ q.all và các lời hứa lồng nhau
- 25. Google Translate iframe workaround
- 26. Giao tiếp giữa các đoạn lồng nhau trong Android
- 27. Java static static Workaround
- 28. Giao dịch trong một Giao dịch trong C#
- 29. WPF Anti aliasing workaround
- 30. AutoMapper và làm phẳng mảng lồng nhau
Cảm ơn. [Documents] (http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#beginTransaction()) cho phép giao dịch lồng nhau, nhưng có vẻ như kết quả giao dịch bên ngoài của tôi bằng cách nào đó bị hủy bỏ bởi một bên trong (mỗi giao dịch giao dịch với cùng một bộ hồ sơ, nhưng cập nhật các cột khác nhau)./Bằng cách này, bạn có biết làm thế nào điều đó có thể xảy ra không?/ Bây giờ tôi sử dụng giao dịch có điều kiện (tương tự như đề xuất của bạn) và vì vậy tôi sẽ gắn bó với nó – sberezin