GreenDao 多表事务操作

场景:Android APP多表操作事务管理

使用Android自带的sql操作类操作的时候需要手动处理事务,使用GreenDao的时候不用管了,啥都处理好了。但是,如果是多表操作的话,怎么统一管理事务?

关键思想是事务嵌套,具体方法使用:

DaoSession().callInTx()

  

看源码可以知道callInTx里面有一层事务管理,实际调用insert、update之类的具体方法的时候,里面还有一层事务。进行事务嵌套后,只要内层的事务有一个操作失败,最外层的事务就认为整个事务都失败,其他操作就回滚了。

以下是示例代码:

public class TransactionTest {
    static String TAG = TransactionTest.class.getName();

    // DaoManager是我自定义的类
    public static boolean a(final long id1, final long id2) {
        try {
            // 还有一个runInTx的方法, 跟callInTx的区别是没返回值. 根据实际情况自由选择就行.
            return DaoManager.getDaoSession().callInTx(new Callable<Boolean>() {
                @Override
                public Boolean call() {
                    TableDao tableDao = DaoManager.getDaoSession().getTableDao();
                    TableAreaDao tableAreaDao = DaoManager.getDaoSession().getTableAreaDao();
                    Table table = new Table();
                    table.setId(id1);    // id主键, 第二次调用肯定主键冲突, 导致异常
                    table.setTable_name("测试桌台 @atearsan");
                    tableDao.insert(table);

                    TableArea area = new TableArea();
                    area.setId(id2);
                    area.setArea_name("测试区域 @atearsan");
                    tableAreaDao.insert(area);

                    return true;
                }
            });
        } catch (Exception e) {
            Log.e(TAG, e.getMessage());
            return false;
        }
    }

    public static boolean b(final long id1, final long id2) {
        try {
            TableDao tableDao = DaoManager.getDaoSession().getTableDao();
            TableAreaDao tableAreaDao = DaoManager.getDaoSession().getTableAreaDao();
            Table table = new Table();
            table.setId(id1);
            table.setTable_name("测试桌台 @atearsan");
            tableDao.insert(table);

            TableArea area = new TableArea();
            area.setId(id2);
            area.setArea_name("测试区域 @atearsan");
            tableAreaDao.insert(area);
            return true;
        } catch (Exception e) {
            Log.e(TAG, e.getMessage());
            return false;
        }
    }

    public static void test() {
        boolean a = a(1, 2); // true
        Log.e(TAG, "a: " + a);
        /*
        执行上面代码: 数据库写入两条数据
         */

        boolean b = b(2, 2);// false, 打印异常日志
        Log.e(TAG, "b: " + b);
        /*
        执行上面代码: Table插入数据, TableArea id冲突, 写入失败
         */

        boolean c = a(3, 2);// false
        Log.e(TAG, "c: " + c);
        /*
        执行上面代码: Table id不会冲突, TableArea id冲突, 但是数据库不会写入数据
         */
    }
}

 

posted @ 2018-12-27 18:43  南下玩技术  阅读(2350)  评论(0编辑  收藏  举报