1. java代码

  MainActivity: 

 1 package com.example.transactiondemo;
 2 
 3 import androidx.appcompat.app.AppCompatActivity;
 4 
 5 import android.os.Bundle;
 6 
 7 public class MainActivity extends AppCompatActivity {
 8 
 9     @Override
10     protected void onCreate(Bundle savedInstanceState) {
11         super.onCreate(savedInstanceState);
12         setContentView(R.layout.activity_main);
13     }
14 }

 

  DatabaseHelper:

 1 package com.example.transactiondemo;
 2 
 3 import android.content.Context;
 4 import android.database.sqlite.SQLiteDatabase;
 5 import android.database.sqlite.SQLiteOpenHelper;
 6 
 7 import androidx.annotation.Nullable;
 8 
 9 
10 //数据库事务
11 //        有两个特点:
12 //        1. 安全性
13 //          由于多条sql语句执行时,倘若中间有报错,那么系统会中断下面语句的执行,从而导致前面部分的语句已经执行
14 //          但后面的没有执行,从而引发安全问题,所以需要调用数据库事务。一旦发生错误就进行回调。
15 //
16 //        2. 高效性
17 //          使用普通的形式向数据库添加很多的数据,与采用数据库事务相比较慢。
18 //          原理是因为没开启事务的时候,总是打开数据库,插入,然后关闭。
19 //          而开启事务的时候,把数据存到内存里面,然后一次性写入。
20 //          journal文件的作用是防止写入的数据过大,先把写入的文件存入journal中,再写入数据库,起到中转作用
21 
22 public class DatabaseHelper extends SQLiteOpenHelper {
23 
24     public DatabaseHelper(Context context) {
25         super(context,"Test.db", null, 1);
26     }
27 
28     @Override
29     public void onCreate(SQLiteDatabase db) {
30         db.execSQL("create table account(id integer, name varchar, money integer)");
31     }
32 
33     @Override
34     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
35 
36     }
37 }

 

  TestDatabase:

 1 package com.example.transactiondemo;
 2 
 3 import android.content.Context;
 4 import android.database.sqlite.SQLiteDatabase;
 5 import android.util.Log;
 6 
 7 import androidx.test.platform.app.InstrumentationRegistry;
 8 
 9 import junit.framework.TestCase;
10 
11 public class TestDatabase extends TestCase {
12 
13     private static final String TAG = "TestDatabase";
14     Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
15     private DatabaseHelper mHelper = new DatabaseHelper(appContext);
16 
17     public void testDatabase(){
18         // 测试数据库创建
19         mHelper.getReadableDatabase();
20     }
21 
22     // 没写Dao层
23     public void testInsert(){
24         SQLiteDatabase db = mHelper.getReadableDatabase();
25 //        db.execSQL("insert into account values(1, 'company', 1000000)");
26 //        db.execSQL("insert into account values(2, 'my_account', 0)");
27 
28         long start = System.currentTimeMillis();
29 
30         db.beginTransaction();
31 
32         for(int i = 0; i < 3000; i++){
33             db.execSQL("insert into account values(1, 'company', 1000000)");
34             db.execSQL("insert into account values(2, 'my_account', 0)");
35         }
36 
37         db.endTransaction();
38         // 输出时间为56793(未启用事务)
39         // 输出时间为969(已启用事务)
40         Log.d(TAG, "timeGap == " + (System.currentTimeMillis() - start));
41         db.close();
42 
43     }
44 
45     public void testUpdate(){
46         // 在这里面转账,其中这个公司的账号-12000,个人账号+12000
47         // 但是由于之间报错,所以公司失去了钱,但是个人账号的钱没有加
48         // 所以需要使用try
49         SQLiteDatabase db = mHelper.getReadableDatabase();
50 
51         // 在try外开始数据库事务,一般放在try语句外
52         db.beginTransaction();
53 
54         try{
55             db.execSQL("update account set money = 1000000 - 12000 where name = 'company'");
56 
57             // 在这里我们让它发生异常
58             //int i = 10 / 0;
59 
60             db.execSQL("update account set money = 12000 where name = 'my_account'");
61 
62             // 如果执行到这,说明没有问题。
63             db.setTransactionSuccessful();
64         }
65         catch(Exception e){
66             throw new RuntimeException("停电了!");
67         }
68         finally {
69             // 如果没有执行setTransactionSuccessful(),那么try中已经执行的数据库语句将会回调,并且该函数的执行需要在数据库连接断开之前
70             db.endTransaction();
71             db.close();
72         }
73 
74     }
75 }

 

posted on 2021-09-07 14:22  EndlessShw  阅读(77)  评论(0)    收藏  举报