编辑:
是,SQLite的doesn't support嵌套事务,但docs声明SQLiteDatabase一样。
情况
我有一个包含事务的方法,我需要从另一个事务中调用这个方法。
此外 - 这两个事务处理同一组记录,但更新不同的列。
问题
看起来我的外部事务的结果被内部的一个取消,仍然都被setTransactionSuccessful()标记为clean并由endTransaction()完成 - 我已经检查过了。
问题
- 任何想法为什么会发生这种情况?
- 有没有推荐的方法来做这样的交易?SQLiteDatabase嵌套事务和解决方法
回答
您可以嵌套事务与Android的SQLite API,与caveats:
交易可以被嵌套。当外部事务结束时,在该事务中完成的所有工作和所有嵌套事务将被提交或回滚。如果任何事务没有被标记为干净(通过调用setTransactionSuccessful),则更改将被回滚。否则他们会承诺。
我见过的一般使用SQLite的另一种方法是,告诉被调用的方法是否应该自行处理交易,或让来电处理事务的布尔参数isInTransaction
通过。
“嵌套Android交易”做而不是使用SQLite嵌套事务/保存点支持。
相反,嵌套的Android事务会抑制显示SQLite事务。嵌套事务不能本身回滚,因为除了外部事务外它不存在。这可以be seen here与mTransactionStack == null
后卫。
只有这样,才能真正支持内嵌事务 - 这SQLite的确实支持,只是不能与开始/提交 - 是手动使用SAVEPOINT/RELEASE命令。当然,设计代码不依赖于此将消除这需要的额外手动管理。
(我可能把所有的事务工作中摆脱个人实际操作,使管理高层主叫方;这工作得相当好了UOW模式,但可能并不总是适用)
现在我结束了对称方法设计(类似于laalto建议),它提供了正确的工作。这是一个解决方法,明确地将嵌套事务“转换”为单一事务。
现在我可以分开或者从另一个地打电话给他们(没有我仍然不明白的副作用)。
这就是:
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();
}
}
您可以通过使用savepoints原始的SQL在execSQL()
以这种方式进行嵌套事务:
db.execSql("SAVEPOINT test"); // declare savepoint
// ... do some operations
db.execSql(";ROLLBACK TO test"); // rollback
db.execSql("RELEASE test"); // save changes
分号ROLLBACK的前面是必需的,因为没有它的Android数据库框架将尝试呼叫endTransaction()
。有关详细信息,请参阅方法android.database.sqlite.SQLiteSession#executeSpecial
和android.database.sqlite.SQLiteSession#execute
的代码。
- 1. 解决方法嵌套while - >获取
- 2. Cython:嵌套式typedefs的解决方法
- 3. 简单的嵌套XSLT解决方案
- 4. 嵌套for循环解决方案
- 5. 嵌套promise和如何解决em
- 6. 春嵌套事务
- 7. EF6嵌套事务
- 8. Dropwizard嵌套事务
- 9. 解决嵌套承诺
- 10. 解决方法嵌套subant特性替代行为(自1.8.0)
- 11. 没有泛型支持的嵌套对象:解决方法
- 12. 针对MSVC2010的嵌套模板解决方法?
- 13. ckeditor bug嵌套divs bug的解决方法?
- 14. NHibernate,MySQL,InnoDB和嵌套事务
- 15. 嵌套方法
- 16. 数据库规范化和嵌套列表 - 无法想象的解决方案
- 17. ADO.NET中的嵌套事务
- 18. Neo4j中的嵌套事务
- 19. JTA嵌套事务锁
- 20. 递归/嵌套事务
- 21. TSQL中的嵌套事务
- 22. 嵌套事务不支持
- 23. Jena TDB:嵌套事务
- 24. Spring上的嵌套事务
- 25. 事务嵌套过程
- 26. 简单的方法来处理嵌套事务
- 27. 尝试在嵌套方法调用中启动/创建新事务的EJB中的嵌套方法调用
- 28. MahApps.Metro NumericUpDown事件解决方法
- 29. JavaScript/jQuery - onhashchange事件解决方法
- 30. C# - Windows 2000 BalloonTip事件解决方法
谢谢。 [文档](http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#beginTransaction())允许嵌套事务,但它看起来像我的外部事务结果在某种程度上被内部事务结果取消事务处理同一组记录,但更新不同的列)。 /顺便说一句,你有任何想法如何可能发生??/ 现在我使用有条件的交易(类似于你的建议),所以我会坚持下去 – sberezin 2014-09-29 19:38:54