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 }
浙公网安备 33010602011771号